This example shows us how to create an OAuth2 API with symfony and uses password grant type. I'll go step by step so that it becomes easy to follow. Since the API uses role_hierarchy to control controller access with @Security("has_roles('xxxxx')") in annotations, password grant type is the best/simplest option to use. See the reference links at the bottom of this post. We're going to use FOSOAuthServerBundle to secure our API.


Important


In example below, I expose client_id and client_secret in request URI to obtain access token for demonstration purposes. You should not do that in real world applications. Instead, you should encode both of them with base64_encode function and add it to request header as Authorization.


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

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

$header = 'Basic '.$base64;

So you should use it like Authorization: Basic aS1hbS1jbGllbnQtaWQ6aS1hbS1jbGllbnQtc2VjcmV0 in your request. On top of that, you should remove username, password and grant_type from URI to send them as parameters encoded with application/x-www-form-urlencoded. Your final request should look like the one below.


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

Definitions



Entity association



Setup unsecured API


Virtual Host


# /etc/apache2/sites-available/oauth-server.dev.conf

<VirtualHost *:80>
ServerName oauth-server.dev
DocumentRoot "/var/www/html/local/oauth-server/web"

<Directory "/var/www/html/local/oauth-server/web">
Options Indexes FollowSymlinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>

ErrorLog ${APACHE_LOG_DIR}/oauth-server.dev.error.log
CustomLog ${APACHE_LOG_DIR}/oauth-server.dev.access.log combined
</VirtualHost>

# etc/hosts

127.0.0.1 oauth-server.dev

$ sudo service apache2 restart

API domain


Setup http://oauth-server.dev/ virtual host.


Install symfony application and bundle


composer create-project symfony/framework-standard-edition oauth-server "2.6.9"
app/console generate:bundle --namespace=Application/ServerBundle

Configuration


Prefix /1/ represents API version in URL.


# oauth-server/app/config/routing.yml
application_server:
resource: "@ApplicationServerBundle/Controller"
prefix: /1/
type: annotation

ServerController


Pay attention to the user roles assigned to methods below. They will be important when creating users with CreateOauthUserCommand below and it will either let or prevent users consuming this API with a client application. Every user must have at least one role.


namespace Application\ServerBundle\Controller;

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

/**
* @Route("server", service="application_server.controller.server")
*/
class ServerController extends Controller
{
/**
* @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
*
* @Security("has_role('ROLE_ADMIN')")
* @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']));
}
}

services:
application_server.controller.server:
class: Application\ServerBundle\Controller\ServerController

Tests


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

# Response
HTTP/1.1 OK - GET your team [inanzzz] from Server

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

# Response
HTTP/1.1 OK - POST your team [inanzzz] to Server

Secure unsecured API


Composer


Install "friendsofsymfony/oauth-server-bundle": "1.4.2" with composer and enable it with new FOS\OAuthServerBundle\FOSOAuthServerBundle() in AppKernel.php file.


Configuration


# oauth-server/app/config/config.yml
fos_oauth_server:
db_driver: orm
client_class: Application\ServerBundle\Entity\Client
access_token_class: Application\ServerBundle\Entity\AccessToken
refresh_token_class: Application\ServerBundle\Entity\RefreshToken
auth_code_class: FOS\OAuthServerBundle\Entity\AuthCode # Not implemented in this example
service:
user_provider: application_server.security.user_provider
options:
supported_scopes: user
access_token_lifetime: 3600

# oauth-server/app/config/routing.yml
fos_oauth_server_token:
resource: "@FOSOAuthServerBundle/Resources/config/routing/token.xml"

# oauth-server/app/config/security.yml
security:
encoders:
Application\ServerBundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 0

role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN

providers:
user_provider:
id: application_server.security.user_provider

firewalls:
oauth_token:
pattern: ^/oauth/v2/token
security: false

secured_area:
pattern: ^/
fos_oauth: true
stateless: true

access_control:
- { path: ^/, roles: [ IS_AUTHENTICATED_FULLY ] }

Client entity


namespace Application\ServerBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\OAuthServerBundle\Entity\Client as BaseClient;

/**
* @ORM\Entity
*/
class Client extends BaseClient
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}

AccessToken entity


namespace Application\ServerBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\OAuthServerBundle\Entity\AccessToken as BaseAccessToken;

/**
* @ORM\Entity
*/
class AccessToken extends BaseAccessToken
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\ManyToOne(targetEntity="Client")
* @ORM\JoinColumn(nullable=false)
*/
protected $client;

/**
* @ORM\ManyToOne(targetEntity="User")
*/
protected $user;
}

RefreshToken entity


namespace Application\ServerBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\OAuthServerBundle\Entity\RefreshToken as BaseRefreshToken;

/**
* @ORM\Entity
*/
class RefreshToken extends BaseRefreshToken
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\ManyToOne(targetEntity="Client")
* @ORM\JoinColumn(nullable=false)
*/
protected $client;

/**
* @ORM\ManyToOne(targetEntity="User")
*/
protected $user;
}

User entity


namespace Application\ServerBundle\Entity;

use Serializable;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass="Application\ServerBundle\Repository\UserRepository")
*/
class User implements UserInterface, Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @ORM\Column(type="string", length=25, unique=true)
*/
private $username;

/**
* @ORM\Column(type="string", length=100, unique=true)
*/
private $email;

/**
* @ORM\Column(type="string", length=32)
*/
private $salt;

/**
* @ORM\Column(type="string", length=40)
*/
private $password;

/**
* @ORM\Column(type="array")
*/
private $roles;

/**
* @ORM\Column(name="is_active", type="boolean")
*/
private $isActive;

public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}

public function getId()
{
return $this->id;
}

public function getUsername()
{
return $this->username;
}

public function setUsername($username)
{
$this->username = $username;
}

public function getEmail()
{
return $this->email;
}

public function setEmail($email)
{
$this->email = $email;
}

public function getSalt()
{
return $this->salt;
}

public function getPassword()
{
return $this->password;
}

public function setPassword($password)
{
$this->password = sha1($password.'{'.$this->salt.'}');
}

public function getRoles()
{
return $this->roles;
}

public function setRoles(array $roles)
{
return $this->roles = $roles;
}

public function serialize()
{
return serialize([$this->id]);
}

public function unserialize($serialized)
{
list ($this->id) = unserialize($serialized);
}

public function eraseCredentials()
{
}
}

User repository


namespace Application\ServerBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;

class UserRepository extends EntityRepository
{
public function findUserByUsername($username)
{
return
$this->createQueryBuilder('u')
->where('u.username = :username')
->setParameter('username', $username)
->getQuery()
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
->getOneOrNullResult(Query::HYDRATE_SIMPLEOBJECT);
}
}

services:
application_server.repository.user:
class: Application\ServerBundle\Repository\UserRepository
factory: [@doctrine.orm.entity_manager, getRepository]
arguments: [Application\ServerBundle\Entity\User]

UserProvider


namespace Application\ServerBundle\Security;

use Application\ServerBundle\Entity\User;
use Application\ServerBundle\Repository\UserRepository;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class UserProvider implements UserProviderInterface
{
private $userRepository;

public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}

public function loadUserByUsername($username)
{
$user = $this->userRepository->findUserByUsername($username);
if (!$user instanceof User) {
throw new UsernameNotFoundException(sprintf('User [%s] cannot be found.', $username));
}

return $user;
}

public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(sprintf('Invalid user [%s] instance.', get_class($user)));
}

return $this->loadUserByUsername($user->getUsername());
}

public function supportsClass($class)
{
return
$this->userRepository->getClassName() === $class
|| is_subclass_of($class, $this->userRepository->getClassName());
}
}

services:
application_server.security.user_provider:
class: Application\ServerBundle\Security\UserProvider
arguments:
- @application_server.repository.user

Create database and entities


app/console doctrine:database:create
app/console doctrine:schema:update --force

Tests


As we can see below, API is now secured.


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

# Response
{
"error":"access_denied",
"error_description":"OAuth2 authentication required"
}


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

# Response
{
"error":"access_denied",
"error_description":"OAuth2 authentication required"
}

Create client credentials


Every client needs client_id, client_secret, username and password to generate access_token that is used in requests to consume API. Command below is used to generate client_id and client_secret.


namespace Application\ServerBundle\Command;

use FOS\OAuthServerBundle\Entity\Client;
use FOS\OAuthServerBundle\Entity\ClientManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class CreateOauthClientCommand extends Command
{
const GRANT_TYPE = 'grant-type';

private $clientManager;

public function __construct(ClientManager $clientManager)
{
parent::__construct();

$this->clientManager = $clientManager;
}

protected function configure()
{
$this
->setName('create:oauth:client')
->setDescription('Creates a new OAuth client.')
->addOption(
self::GRANT_TYPE,
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'Sets allowed grant type for client. Can be used multiple times.'
);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
/** @var Client $client */
$client = $this->clientManager->createClient();
$client->setAllowedGrantTypes($input->getOption(self::GRANT_TYPE));

$this->clientManager->updateClient($client);

$this->echoCredentials($output, $client);
}

private function echoCredentials(OutputInterface $output, Client $client)
{
$output->writeln('OAuth client has been created...');
$output->writeln(sprintf('Public ID: %s', $client->getPublicId()));
$output->writeln(sprintf('Secret ID: %s', $client->getSecret()));
}
}

services:
application_server.command.create_oauth_client:
class: Application\ServerBundle\Command\CreateOauthClientCommand
arguments:
- @fos_oauth_server.client_manager.default
tags:
- { name: console.command }

Run command below and do not distribute credentials! This will add a new record in client table in database.


MacBook-Pro:oauth-server inanzzz$ php app/console create:oauth:client --grant-type="password" --grant-type="refresh_token"
OAuth client has been created...
Public ID: 1_4ufi1moz9pk4sgk08o004wwo0csggscs4c08wsgcc4wco4s8ws
Secret ID: 4rdg7f3uwigw84ssc8scw00440osg8ck4k8swoog0cwosk40ko

Create user information


Every client needs client_id, client_secret, username and password to generate access_token that is used in requests to consume API. Command below is used to generate username and password. Every user must have at least one role.


namespace Application\ServerBundle\Command;

use Application\ServerBundle\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;

class CreateOauthUserCommand extends Command
{
const USERNAME = 'username';
const EMAIL = 'email';
const PASSWORD = 'password';
const ROLE = 'role';
const PATTERN = '/^[a-zA-Z0-9]+$/';

private $validRoles = ['ROLE_USER', 'ROLE_ADMIN', 'ROLE_SUPER_ADMIN'];
private $entityManager;

public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct();

$this->entityManager = $entityManager;
}

protected function configure()
{
$this
->setName('create:oauth:user')
->setDescription('Creates a new OAuth user.')
->addOption(
self::USERNAME,
null,
InputOption::VALUE_REQUIRED,
'Sets username for user.'
)
->addOption(
self::PASSWORD,
null,
InputOption::VALUE_REQUIRED,
'Sets password for user.'
)
->addOption(
self::EMAIL,
null,
InputOption::VALUE_REQUIRED,
'Sets email for user.'
)
->addOption(
self::ROLE,
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'Sets allowed role for user. Can be used multiple times.'
);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->validatePassword($input->getOption(self::PASSWORD));
$this->validateEmail($input->getOption(self::EMAIL));
$roles = $this->validateRoles($input->getOption(self::ROLE));

$user = new User();
$user->setUsername($input->getOption(self::USERNAME));
$user->setPassword($input->getOption(self::PASSWORD));
$user->setEmail($input->getOption(self::EMAIL));
$user->setRoles($roles);

$this->entityManager->persist($user);
$this->entityManager->flush();

$this->echoCredentials($input, $output);
}

private function validatePassword($password)
{
if (!preg_match(self::PATTERN, $password)) {
throw new BadCredentialsException(sprintf('Password must contain only numbers and letters.'));
}
}

private function validateEmail($email)
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new BadCredentialsException(sprintf('Email must be a valid value.'));
}
}

private function validateRoles($roles)
{
$result = null;
foreach ($roles as $role) {
if (in_array($role, $this->validRoles)) {
$result[] = $role;
}
}

if (!$result) {
throw new InvalidOptionsException(sprintf('Role(s) must be a valid option.'));
}

return $result;
}

private function echoCredentials(InputInterface $input, OutputInterface $output)
{
$output->writeln('OAuth user has been created...');
$output->writeln(sprintf('Username: %s', $input->getOption(self::USERNAME)));
$output->writeln(sprintf('Password: %s', $input->getOption(self::PASSWORD)));
$output->writeln(sprintf('Roles: %s', json_encode($input->getOption(self::ROLE))));
}
}

services:
application_server.command.create_oauth_user:
class: Application\ServerBundle\Command\CreateOauthUserCommand
arguments:
- @doctrine.orm.entity_manager
tags:
- { name: console.command }

Run command below and do not distribute credentials! You actually don't need to set ROLE_USER because you already set ROLE_ADMIN which also covers ROLE_USER as we know. I've just set it as demonstration purposes. If you set ROLE_SUPER_USER to a new method in ServerController above, this user won't be able to access it via client application. This will add a new record in user table in database.


MacBook-Pro:oauth-server inanzzz$ php app/console create:oauth:user --username=inanzzz --password=123123 --email=myemail@mydomain.com --role=ROLE_USER --role=ROLE_ADMIN
OAuth user has been created...
Username: inanzzz
Password: 123123
Roles: ["ROLE_USER","ROLE_ADMIN"]

Getting Access Token


This will add a new record in access_token and refresh_token table in database.


Postman.


# Request
GET http://oauth-server.dev/app_dev.php/oauth/v2/token?client_id=1_4ufi1moz9pk4sgk08o004wwo0csggscs4c08wsgcc4wco4s8ws&client_secret=4rdg7f3uwigw84ssc8scw00440osg8ck4k8swoog0cwosk40ko&grant_type=password&username=inanzzz&password=123123

# Response
HTTP/1.1 200 OK
{
"access_token": "MDgzYzhhMjYxY2E5ZDQ0NmVjMTY1ZDJhYTBmMzMzODM3YTE3NmUyOGMyMTVmMjBlM2VjNjRiYTcxZjBjMjUwYQ",
"expires_in": 3600,
"token_type": "bearer",
"scope": "user",
"refresh_token": "MDgzNjVkNTE1Y2ZjZGM5ZTEyYWNlNGQyNDAyZmNjZDNmMzg1ZGJkOTdiMTdhY2FhYWNlNDg1M2ViMWJjOWE0ZA"
}

Curl.


# Request
curl 'http://oauth-server.dev/app_dev.php/oauth/v2/token?client_id=1_fqnumqc8gvkss8soo44g4g0sw0s0okkk8og84k8ggckwsk4gc&client_secret=1m5d8yl0wk00wogsskoooo4k4o0wgw8k00cw8k00s4g8w8gkw0&grant_type=password&username=inanzzz&password=123123'

# Response
HTTP/1.1 200 OK
{
"access_token": "MDgzYzhhMjYxY2E5ZDQ0NmVjMTY1ZDJhYTBmMzMzODM3YTE3NmUyOGMyMTVmMjBlM2VjNjRiYTcxZjBjMjUwYQ",
"expires_in": 3600,
"token_type": "bearer",
"scope": "user",
"refresh_token": "MDgzNjVkNTE1Y2ZjZGM5ZTEyYWNlNGQyNDAyZmNjZDNmMzg1ZGJkOTdiMTdhY2FhYWNlNDg1M2ViMWJjOWE0ZA"
}

Symfony.


# Request
public function indexAction()
{
$oauthHeaders = [
"client_id" => "1_4ufi1moz9pk4sgk08o004wwo0csggscs4c08wsgcc4wco4s8ws",
"client_secret" => "4rdg7f3uwigw84ssc8scw00440osg8ck4k8swoog0cwosk40ko",
"grant_type" => "password",
"username" => "inanzzz",
"password" => "123123"
];

$endpoint = "http://oauth-server.dev/app_dev.php/oauth/v2/token";

$curl = curl_init($endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, 'Content-Type: application/x-www-form-urlencoded');
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($oauthHeaders));
$response = curl_exec($curl);
curl_close($curl);

return new Response($response);
}

# Response
HTTP/1.1 200 OK
{
"access_token": "MmI3Y2RhZWMzNzA0YWU3OGRhNzg4ZGQ0MmFmMjdlNzkyOTk0ZjBjYTg5MjAxMDYwZGI1MGQxMWI3MWU2MzM1Ng",
"expires_in": 3600,
"token_type": "bearer",
"scope": "user",
"refresh_token": "ZDljY2FlNTk4N2Y5MDU5MTAzNzg0OWFjNDExODJhYmMzYmRkODliOWJiMTk0ZmNjOGZkYmU2MTY2YTZiYWEwYw"
}

Getting Access Token with Refresh Token


Postman.


# Request
GET http://oauth-server.dev/app_dev.php/oauth/v2/token?client_id=1_4ufi1moz9pk4sgk08o004wwo0csggscs4c08wsgcc4wco4s8ws&client_secret=4rdg7f3uwigw84ssc8scw00440osg8ck4k8swoog0cwosk40ko&grant_type=refresh_token&refresh_token=ZDljY2FlNTk4N2Y5MDU5MTAzNzg0OWFjNDExODJhYmMzYmRkODliOWJiMTk0ZmNjOGZkYmU2MTY2YTZiYWEwYw

# Response
HTTP/1.1 200 OK
{
"access_token": "NzhkZTc3MWMzN2Y4YmZlOGM3MWM5NDc2NGI5NmJjNjg5NjRkMzliZDFjZjYwNmFjODM3ZmM0MjI1NjE4NWM1OA",
"expires_in": 3600,
"token_type": "bearer",
"scope": "user",
"refresh_token": "ODEzOGY1MTUxNTZhZTFmNjg0ZDRlODVjZTZiYjg2MzRiZmM2ZTRhZWNjYWU5ODBkNjJjOWNlNmZlYTYzMWJmZA"
}

Curl.


# Request
curl 'http://oauth-server.dev/app_dev.php/oauth/v2/token?client_id=1_fqnumqc8gvkss8soo44g4g0sw0s0okkk8og84k8ggckwsk4gc&client_secret=1m5d8yl0wk00wogsskoooo4k4o0wgw8k00cw8k00s4g8w8gkw0&grant_type=refresh_token&refresh_token=NWM3NTc4MmQxNTNiMDQ4ZTQzNGNjODcxNDc2YjQ2Zjg4ZWRkNWQ4YTFlOTIxNjU4Mjc2MTRhNmNhMGQ2NmQ0YQ'

# Response
HTTP/1.1 200 OK
{
"access_token": "NjRiMjQ5NDA2OTU4MGRjNTg2YWQxY2UyZGZhY2ZiMDVkOTg4ZTViNTY1NDljNWZlZDUxZWEwZDM5NTViMTYyZQ",
"expires_in": 3600,
"token_type": "bearer",
"scope": "user",
"refresh_token": "ZTVkNGFiN2UwMTEzMTUwNmRiMmFkZWIzZTM3Y2E4MTUxMzI3MDE2N2Y2NGMwY2QwMTYwZTE1YmQyMDE5ZWY3Yg"
}

Symfony.


# Request
public function indexAction()
{
$oauthHeaders = [
"client_id" => "1_4ufi1moz9pk4sgk08o004wwo0csggscs4c08wsgcc4wco4s8ws",
"client_secret" => "4rdg7f3uwigw84ssc8scw00440osg8ck4k8swoog0cwosk40ko",
"grant_type" => "refresh_token",
"refresh_token" => "ODEzOGY1MTUxNTZhZTFmNjg0ZDRlODVjZTZiYjg2MzRiZmM2ZTRhZWNjYWU5ODBkNjJjOWNlNmZlYTYzMWJmZA"
];

$endpoint = "http://oauth-server.dev/app_dev.php/oauth/v2/token";

$curl = curl_init($endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, 'Content-Type: application/x-www-form-urlencoded');
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($oauthHeaders));
$response = curl_exec($curl);
curl_close($curl);

return new Response($response);
}

# Response
HTTP/1.1 200 OK
{
"access_token": "MGRlYzMzYjdiMmViMGQxNDZlMjljZTViODgxMTI1NWY4OWZlMmM3ZDZhYWE2NGE0NDljY2M2MDQxMmM5YTRkZQ",
"expires_in": 3600,
"token_type": "bearer",
"scope": "user",
"refresh_token": "ZmY4MzYyMDBlZDAzNmE0OWQyNjEyNTQ1YTMyOGNjOGQ5OWQyOTAwYjNmNzViNDlkMTI5OWZhNzNlMTYzN2Y1OQ"
}

Verify if Access Token works


Curl.


# Request
curl -H "Authorization: Bearer MGRlYzMzYjdiMmViMGQxNDZlMjljZTViODgxMTI1NWY4OWZlMmM3ZDZhYWE2NGE0NDljY2M2MDQxMmM5YTRkZQ" http://oauth-server.dev/app_dev.php/1/server/team/inanzzz

# Response
HTTP/1.1 200 OK
GET your team [inanzzz] from Server

# Request
curl -v -X POST -H "Authorization: Bearer MGRlYzMzYjdiMmViMGQxNDZlMjljZTViODgxMTI1NWY4OWZlMmM3ZDZhYWE2NGE0NDljY2M2MDQxMmM5YTRkZQ" "Content-type:application-json" -d '{"name":"inanzzz"}' http://oauth-server.dev/app_dev.php/1/server/team

# Response
HTTP/1.1 200 OK
POST your team [inanzzz] to Server

Symfony.


# Request
public function indexAction()
{
$oauthHeaders = [
'Authorization: Bearer MGRlYzMzYjdiMmViMGQxNDZlMjljZTViODgxMTI1NWY4OWZlMmM3ZDZhYWE2NGE0NDljY2M2MDQxMmM5YTRkZQ'
];

$endpoint = "http://oauth-server.dev/app_dev.php/1/server/team/inanzzz";

$curl = curl_init($endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $oauthHeaders);
$response = curl_exec($curl);
curl_close($curl);

return new Response($response);
}

# Response
HTTP/1.1 200 OK
GET your team [inanzzz] from Server

# Request
public function indexAction(Request $request)
{
$oauthHeaders = [
'Authorization: Bearer MGRlYzMzYjdiMmViMGQxNDZlMjljZTViODgxMTI1NWY4OWZlMmM3ZDZhYWE2NGE0NDljY2M2MDQxMmM5YTRkZQ'
];

$endpoint = "http://oauth-server.dev/app_dev.php/1/server/team";

$curl = curl_init($endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $oauthHeaders);
curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getContent());
$response = curl_exec($curl);
curl_close($curl);

return new Response($response);
}

# Response
HTTP/1.1 200 OK
POST your team [inanzzz] to Server

Request with an expired access_token.


# Request
curl -v -H "Authorization: Bearer MDgzYzhhMjYxY2E5ZDQ0NmVjMTY1ZDJhYTBmMzMzODM3YTE3NmUyOGMyMTVmMjBlM2VjNjRiYTcxZjBjMjUwYQ" http://oauth-server.dev/app_dev.php/1/server/team/inanzzz

# Response
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to oauth-server.dev (127.0.0.1) port 80 (#0)
> GET /app_dev.php/1/server/team/inanzzz HTTP/1.1
> User-Agent: curl/7.37.1
> Host: oauth-server.dev
> Accept: */*
> Authorization: Bearer MDgzYzhhMjYxY2E5ZDQ0NmVjMTY1ZDJhYTBmMzMzODM3YTE3NmUyOGMyMTVmMjBlM2VjNjRiYTcxZjBjMjUwYQ
>
< HTTP/1.1 401 Unauthorized
< Date: Sun, 10 Jan 2016 12:06:07 GMT
* Server Apache/2.4.10 (Unix) PHP/5.6.9 is not blacklisted
< Server: Apache/2.4.10 (Unix) PHP/5.6.9
< Vary: Authorization
< X-Powered-By: PHP/5.6.9
< WWW-Authenticate: Bearer realm="Service", error="invalid_grant", error_description="The access token provided has expired."
< Cache-Control: no-store, private
< Pragma: no-cache
< X-Debug-Token: 02a119
< X-Debug-Token-Link: /app_dev.php/_profiler/02a119
< Content-Length: 86
< Content-Type: application/json
<
* Connection #0 to host oauth-server.dev left intact
{"error":"invalid_grant","error_description":"The access token provided has expired."}

Request a new access_token with an expired refresh_token.


# Request
GET http://oauth-server.dev/app_dev.php/oauth/v2/token?client_id=1_4ufi1moz9pk4sgk08o004wwo0csggscs4c08wsgcc4wco4s8ws&client_secret=4rdg7f3uwigw84ssc8scw00440osg8ck4k8swoog0cwosk40ko&grant_type=refresh_token&refresh_token=NDllMzg1MmYxZTcwZDg0NDFiMWNiMDU3Y2U3NzVlMDhiN2ZkYTRiMmE5NTdhODFhNDVkZDliYzQyNzk5OGFiNg

# Response
HTTP/1.1 400 Bad Request
{
"error": "invalid_grant",
"error_description": "Refresh token has expired"
}

References


For more information, you can check links below.