Skip to content

Creating custom grants

Alex Bilbie edited this page May 9, 2013 · 8 revisions

Creating your own grant is simple, just need to write a class that implements League\OAuth2\Server\Grant\GrantTypeInterface.

Once you've written it you can enable it like so:

$server->addGrantType(new MyGrantType($server));

The following methods need to be implemented:

__construct(Authorization $authServer)

This method should set $authServer to a protected variable inside the class so that it can make use of the parent authorization server class and call methods from other grants.


getResponseType()

If your grant can be used from a user flow (as the AuthCode grant does) then this should respond with a string that is used to identify the grant in the query string:

i.e. where the XXXXXX is in http://oauth2-auth-server/authorise?client_id=foo&redirect=http://foo/bar&response_type=XXXXXX

If your grant doesn't allow for this then just return null


getIdentifier()

This method is called when a client tries to get an access token from the authorization server.

The method should respond with a URL safe string which represents the name of your grant, e.g. authorization_code or client_credentials.


completeFlow($inputParams = null)

This method is called by the Authorization server class once it has asserted that the grant type being used by the client is your custom grant.

This method should respond with an array like so:

array(
    'access_token'  =>  (string),	// The access token
    'refresh_token' =>  (string),	// The refresh token (only set if the refresh token grant is enabled)
    'token_type'    =>  'bearer',	// Almost always "bearer" (exceptions: JWT, SAML)
    'expires'       =>  (int),		// The timestamp of when the access token will expire
    'expires_in'    =>  (int)		// The number of seconds before the access token will expire
)

You should use the getParam() method of the authorization server to verify the existance of any POST parameters you need.

For example the client credentials grant requires the following parameters: client_id, client_secret.

It gets these parameters from the request by calling:

$authParams = $this->authServer->getParam(array('client_id', 'client_secret'), 'post', $inputParams);

Then it ensures the parameters aren't null and are valid (see the source of any of the built-in grant types for an example of how to do this) before validating any scopes sent along with the request.

Before responding a new session needs to be created an access token associated:

$sessionId = $this->authServer->getStorage('session')->createSession($authParams['client_id'], 'OWNER TYPE', 'OWNER ID');

The OWNER TYPE should be user (if the access token is owned by a user) or client (if the access token is owned by a client). The OWNER ID should the ID of the OWNER TYPE (cast as a string)

Then an access token is generated

// Generate an access token
$accessToken = SecureKey::make();
$accessTokenExpiresIn = $this->authServer->getAccessTokenTTL();
$accessTokenExpires = time() + $accessTokenExpiresIn;

The access token is associated with the session:

$accessTokenId = $this->authServer->getStorage('session')->associateAccessToken($sessionId, $accessToken, $accessTokenExpires);

Any scopes should be associated with the access token (see one of the built-in grant on how to do this).

Finally the function returns the response:

$response = array(
    'access_token'  =>  $accessToken,
    'token_type'    =>  'bearer',
    'expires'       =>  $accessTokenExpires,
    'expires_in'    =>  $accessTokenExpiresIn
);

return $response;

If your grant allows refresh tokens and the refresh tokens grant has been enabled to be used then the response will look like this:

$response = array(
    'access_token'  =>  $accessToken,
    'token_type'    =>  'bearer',
    'expires'       =>  $accessTokenExpires,
    'expires_in'    =>  $accessTokenExpiresIn
);

// Associate a refresh token if set
if ($this->authServer->hasGrantType('refresh_token')) {
    $refreshToken = SecureKey::make();
    $refreshTokenTTL = time() + $this->authServer->getGrantType('refresh_token')->getRefreshTokenTTL();
    $this->authServer->getStorage('session')->associateRefreshToken($accessTokenId, $refreshToken, $refreshTokenTTL);
    $response['refresh_token'] = $refreshToken;
}

return $response;