05/01/2016 - SYMFONY
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.
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
refresh_token
içermez.access_token
varsayılan olarak "user" bilgisine sahip değildir bu nedenle, API/server uygulamasında "user" bilgisine ulaşmak mümkün olmaz. Sadece Authorization Code, Implicit Grant ve Password access_token
varsayılan olarak "user" bilgisine sahiplerdir.Composer ile "guzzlehttp/guzzle": "6.1.1"
paketini yükleyin.
# 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
# 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%
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
]
);
}
}
# 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']));
}
# 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
Daha fazla bilgi için, aşağıdaki linkleri kontrol edebilirsiniz.