A PHP7.2+ OAuth client core library

2.1.1 2019-03-08 09:41 UTC


Packagist version License Travis CI CodeCov Scrunitizer CI Packagist downloads PayPal donate



  • PHP 7.2+
  • a PSR-18 compatible HTTP client library of your choice
    • optional PSR-17 compatible Request-, Response- and UriFactories
  • see chillerlan/php-oauth for already implemented providers

Getting Started

In order to instance an OAuthInterface you you'll need to invoke a PSR-18 ClientInterface, a OAuthStorageInterface and OAuthOptions (a SettingsContainerInterface) objects first:

use chillerlan\OAuth\Providers\<PROVIDER_NAMESPACE>\<PROVIDER>;
use chillerlan\OAuth\{OAuthOptions, Storage\SessionTokenStorage};
use <PSR-18 HTTP Client>;

// OAuthOptions
$options = new OAuthOptions([
	// OAuthOptions
	'key'         => '<API_KEY>',
	'secret'      => '<API_SECRET>',
	'callbackURL' => '<API_CALLBACK_URL>',

// a \Psr\Http\Client\ClientInterface
$http = new HttpClient;

// OAuthStorageInterface
// a persistent storage is required for authentication!
$storage = new SessionTokenStorage($options);

// an optional \Psr\LoggerInterface logger
$logger = new Logger;

// invoke and use the OAuthInterface
$provider = new Provider($http, $storage, $options, $logger);


The application flow may differ slightly depending on the provider; there's a working authentication example in the provider repository.

Step 1: optional login link

Display a login link and provide the user with information what kind of data you're about to access; ask them for permission to save the access token if needed.

echo '<a href="?login='.$provider->serviceName.'">connect with '.$provider->serviceName.'!</a>';

Step 2: redirect to the provider

Redirect to the provider's login screen with optional arguments in the authentication URL, like permissions, scopes etc.

// optional scopes for OAuth2 providers
$scopes = [

if(isset($_GET['login']) && $_GET['login'] === $provider->serviceName){
	header('Location: '.$provider->getAuthURL(['extra-param' => 'val'], $scopes));

Step 3: receive the token

Receive the access token, save it, do whatever you need to do, then redirect to step 4


if(isset($_GET['oauth_token']) && isset($_GET['oauth_verifier'])){
	$token = $provider->getAccessToken($_GET['oauth_token'], $_GET['oauth_verifier']);

	// save & redirect...


usage of the <state> parameter depends on the provider

	$token = $provider->getAccessToken($_GET['code'], $_GET['state'] ?? null);

	// save & redirect...

Step 4: auth Granted

After receiving the access token, go on and verify it then use the API.

if(isset($_GET['granted']) && $_GET['granted'] === $provider->serviceName){
	$response = $provider->doStuff();
	// ...

Call the Provider's API

After successfully receiving the Token, we're ready to make API requests:

// import a token to the OAuth token storage if needed
$storage->storeAccessToken($provider->serviceName, new AccessToken->__fromJSON($token_json));

// make a request
$response = $provider->request(
	['q' => 'param'], 
	['data' => 'content'], 
	['content-type' => 'whatever']

// use the data: $response is a PSR-7 ResponseInterface
$headers = $response->getHeaders();
$data    = $response->getBody()->getContents();


In order to use a provider or storage, that is not yet supported, you'll need to implement the respective interfaces:


The OAuth1 implementation is close to Twitter's specs and should work for most other OAuth1 services.

use chillerlan\OAuth\Core\OAuth1Provider;

class MyOauth1Provider extends Oauth1Provider{

	protected $apiURL          = '';
	protected $requestTokenURL = '';
	protected $authURL         = '';
	protected $accessTokenURL  = '';



OAuth2 is a very straightforward... mess. Please refer to your provider's docs for implementation details.

use chillerlan\OAuth\Core\OAuth2Provider;

class MyOauth2Provider extends Oauth2Provider implements ClientCredentials, CSRFToken, TokenExpires, TokenRefresh{
	use OAuth2ClientCredentialsTrait, OAuth2CSRFTokenTrait, OAuth2TokenRefreshTrait;

	public const SCOPE_WHATEVER = 'whatever';

	protected $apiURL                    = '';
	protected $authURL                   = '';
	protected $accessTokenURL            = '';
	protected $clientCredentialsTokenURL = '';
	protected $authMethod                = self::HEADER_BEARER;
	protected $authHeaders               = ['Accept' => 'application/json'];
	protected $apiHeaders                = ['Accept' => 'application/json'];
	protected $scopesDelimiter           = ',';



There are 2 different OAuthStorageInterface, refer to these for implementation details (extend OAuthStorageAbstract):

  • MemoryStorage: non-persistent, to store an existing token during script runtime and then discard it.
  • SessionStorage: (half-)persistent, stores a token for as long a user's session is alive, e.g. while authenticating.



Implements PSR-18 ClientInterface and PSR-3LoggerAwareInterface.

method return
__construct(ClientInterface $http, OAuthStorageInterface $storage, SettingsContainerInterface $options) -
getAuthURL(array $params = null) PSR-7 UriInterface
request(string $path, array $params = null, string $method = null, $body = null, array $headers = null) PSR-7 ResponseInterface
setRequestFactory(RequestFactoryInterface $requestFactory) OAuthInterface
setStreamFactory(StreamFactoryInterface $streamFactory) OAuthInterface
setUriFactory(UriFactoryInterface $uriFactory) OAuthInterface
property description
$serviceName the classname for the current provider
$accessTokenURL the provider`s access token URL
$authURL the provider`s authentication token URL
$revokeURL an optional URL to revoke an access token (via API)
$userRevokeURL an optional link to the provider's user control panel where they can revoke the current token


method return
getAccessToken(string $token, string $verifier, string $tokenSecret = null) AccessToken
getRequestToken() AccessToken


method return
getAccessToken(string $code, string $state = null) AccessToken
getAuthURL(array $params = null, $scopes = null) PSR-7 UriInterface


implemented by OAuth2ClientCredentialsTrait

method return
getClientCredentialsToken(array $scopes = null) AccessToken


implemented by OAuth2CSRFTokenTrait

method return
(protected) checkState(string $state = null) OAuth2Interface
(protected) setState(array $params) array


implemented by OAuth2TokenRefreshTrait

method return
refreshAccessToken(AccessToken $token = null) AccessToken



method return
storeAccessToken(string $service, AccessToken $token) OAuthStorageInterface
getAccessToken(string $service) AccessToken
hasAccessToken(string $service) bool
clearAccessToken(string$service) OAuthStorageInterface
clearAllAccessTokens() OAuthStorageInterface
storeCSRFState(string $service, string $state) OAuthStorageInterface
getCSRFState(string $service) string
hasCSRFState(string $service) bool
clearCSRFState(string $service) OAuthStorageInterface
clearAllCSRFStates() OAuthStorageInterface
toStorage(AccessToken $token) string
fromStorage(string $data) AccessToken


method return description
__construct(array $properties = null) -
__set(string $property, $value) void overrides chillerlan\Traits\Container
setExpiry(int $expires = null) AccessToken
isExpired() bool
property type default allowed description
$requestToken string null * OAuth1 only
$requestTokenSecret string null * OAuth1 only
$accessTokenSecret string null * OAuth1 only
$accessToken string null *
$refreshToken string null *
$extraParams array []
$expires int AccessToken::EOL_UNKNOWN
$provider string null *


OAuth tokens are secrets and should be treated as such. Store them in a safe place, consider encryption.
I won't take responsibility for stolen auth tokens. Use at your own risk.