Bu örnek bize symfony ile client_credentials grant type kullanan bir OAuth2 API clientın nasıl yaratılacağını gösterecek ve daha önceden yazdığım OAuth2 API server ile ilişkilidir. Anlaşılması için adımları tek tek gideceğim. Eğer API @Security("has_role('xxxxx')") annotation ile controllerleri control etmek için role_hierarchy kullanmıyor ise, client_credentials grant type en uygun ve basit seçenektir. Daha fazla bilgi için, yazının en altındaki referans linklerini de ziyaret edebilirsiniz.


Önemli


Aşağıdaki örnekte, access token'i elde etmek için kullandığım isteğin URI kısmında client_id ve client_secret bilgilerini sadece göstermek amacıyla açıkça teşhir ettim. Gerçek hayattaki uygulamalarınızda bunu yapmamalısınız. Onun yerine, her ikisini de base64_encode fonksiyonu ile kodlayıp, isteğin kafasına Authorization olarak ekleyin.


$clientId = 'i-am-client-id';
$clientSecret = 'i-am-client-secret';

$base64 = base64_encode($clientId.':'.$clientSecret);

$header = 'Basic '.$base64;

Sonuç olarak isteğinizde Authorization: Basic aS1hbS1jbGllbnQtaWQ6aS1hbS1jbGllbnQtc2VjcmV0 şeklinde kullanmanız gerekir. Bununla birlikte, URI kısmından grant_type girdilerinide kaldırıp, application/x-www-form-urlencoded ile kodlanmak üzere, istek parametresi olarak kullanmanız gerekir. Final isteğiniz aşağıdaki gibi olmalı.


curl -X POST
-H 'Authorization: Basic aS1hbS1jbGllbnQtaWQ6aS1hbS1jbGllbnQtc2VjcmV0'
-H 'content-type: application/x-www-form-urlencoded'
-d 'grant_type=client_credentials'
http://oauth-server.dev/app_dev.php/oauth/v2/token

Gerçekler



Composer.json


Composer ile "guzzlehttp/guzzle": "6.1.1" paketini yükleyin.


Parameters.yml


# oauth-client/app/config/parameters.yml
parameters:
oauth_api_access_token_cache_namespace: OAUTH2_ACCESS_TOKEN
oauth_api_base_url: http://oauth-server.dev/app_dev.php
oauth_api_uri_version: /1
oauth_api_token_uri: /oauth/v2/token?client_id=8_4mcij3t948isk880w0gskkksc88w0wo0wowogkgcowk4coocwk&client_secret=4gxi02iydlwkwokko4cs8w4skw8goks0s00cw00okosskcg8sg&grant_type=client_credentials

Controllers.yml


# oauth-client/src/Application/ClientBundle/Resources/config/controllers.yml
services:
application_client.controller.team:
class: Application\ClientBundle\Controller\TeamController
arguments:
- %oauth_api_access_token_cache_namespace%
- %oauth_api_base_url%
- %oauth_api_uri_version%
- %oauth_api_token_uri%

TeamController.php


Bu örnek her istek için yeni bir access_token yaratır ki buda sistemin yavaş çalışmasına neden olur. Sorunu çözmek için access_token'i cache de tutun ve sadece süresi bitince yeniden yaratın. Ayrıca, aşağıdaki kodları mümkün olduğunca service, model, factory, helper gibi classlara bölün.


namespace Application\ClientBundle\Controller;

use GuzzleHttp\Client;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* @Route("team", service="application_client.controller.team")
*/
class TeamController extends Controller
{
private $oauthApiAccessTokenCacheNamespace;
private $oauthApiBaseUrl;
private $oauthApiUriVersion;
private $oauthApiTokenUri;

public function __construct(
$oauthApiAccessTokenCacheNamespace,
$oauthApiBaseUrl,
$oauthApiUriVersion,
$oauthApiTokenUri
) {
$this->oauthApiAccessTokenCacheNamespace = $oauthApiAccessTokenCacheNamespace;
$this->oauthApiBaseUrl = $oauthApiBaseUrl;
$this->oauthApiUriVersion = $oauthApiUriVersion;
$this->oauthApiTokenUri = $oauthApiTokenUri;
}

/**
* @param string $name
*
* @Method({"GET"})
* @Route("/{name}")
*
* @return Response
*/
public function getTeamAction($name)
{
$accessToken = $this->getAccessToken();
$response= $this->call(
'GET',
$this->oauthApiUriVersion.'/server/team/'.$name,
$accessToken
);

return new Response($response->getBody().' with ACCESS TOKEN: '.$accessToken);
}

/**
* @param Request $request
*
* @Method({"POST"})
* @Route("")
*
* @return Response
*/
public function createTeamAction(Request $request)
{
$accessToken = $this->getAccessToken();
$response= $this->call(
'POST',
$this->oauthApiUriVersion.'/server/team',
$accessToken,
$request->getContent()
);

return new Response($response->getBody().' with ACCESS TOKEN: '.$accessToken);
}

private function getAccessToken()
{
$response = $this->call('GET', $this->oauthApiTokenUri);
$responseParts = json_decode($response->getBody(), true);

return $responseParts['access_token'];
}

private function call($method, $uri, $auth = null, $postData = null)
{
$client = new Client();

return $client->request(
$method,
$this->oauthApiBaseUrl.$uri,
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer '.$auth
],
'body' => $postData
]
);
}
}

Server side methodları


# oauth-server/src/Application/ServerBundle/Controller/ServerController.php
/**
* @param string $name
*
* @Method({"GET"})
* @Route("/team/{name}")
*
* @return Response
*/
public function getTeamAction($name)
{
return new Response(sprintf('GET your team [%s] from Server', $name));
}

/**
* @param Request $request
*
* @Method({"POST"})
* @Route("/team")
*
* @return Response
*/
public function createTeamAction(Request $request)
{
$postData = json_decode($request->getContent(), true);

return new Response(sprintf('POST your team [%s] to Server', $postData['name']));
}

Testler


# Request
GET http://oauth-client.dev/app_dev.php/team/inanzzz

# Response
GET your team [inanzzz] from Server with ACCESS TOKEN: YjQ0ZjVhMDE4MmRhMDIyYWQyMzhhODM4M2YzMGRmMzc0ODI2ZWU4NWFiMmJhZGUyOTQ0OTA3Y2MyNDhkMzYyMw

# Request
POST http://oauth-client.dev/app_dev.php/team
{
"name": "inanzzz"
}

# Response
POST your team [inanzzz] to Server with ACCESS TOKEN: ZTllODdhZTRlY2VmYzdhYmU4ZmI5MjUxMDQ1MjI0YjMzZjAxN2E3YzQxZmUwNjljMDMyZjg1OTZhODUwMGI0ZA

Referanslar


Daha fazla bilgi için, aşağıdaki linkleri kontrol edebilirsiniz.