This package provides OpenID OAuth 2.0 support for the PHP League's OAuth 2.0 Client.
Project
master-branch (alias stable, latest)
This package is compliant with PSR-1, PSR-2 and PSR-4. If you notice compliance oversights, please send a patch via pull request.
The following versions of PHP are supported.
- PHP 7.1
- PHP 7.2
- PHP 7.3
- PHP 7.4
- HHVM
OpenID App will also need to be set up, which
will provide you with the {app-id}
and {app-secret}
required (see Usage below).
To install, use composer:
composer require d3strukt0r/oauth2-openid
$provider = new Generation2\OAuth2\Client\Provider\Generation2Provider([
'clientId' => '{app-id}', // The client ID assigned to you by the provider
'clientSecret' => '{app-secret}', // The client password assigned to you by the provider
'redirectUri' => 'https://example.com/callback-url',
]);
if (!empty($_GET['error'])) {
// Got an error, probably user denied access
unset($_SESSION['oauth2state']);
exit('Got error: '.htmlspecialchars($_GET['error_description']).' ('.htmlspecialchars($_GET['error']).')');
// If we don't have an authorization code then get one
} elseif (!isset($_GET['code'])) {
// Fetch the authorization URL from the provider; this returns the
// urlAuthorize option and generates and applies any necessary parameters
// (e.g. state).
$authorizationUrl = $provider->getAuthorizationUrl([
'scope' => 'user:id user:email',
]);
// Get the state generated for you and store it to the session.
$_SESSION['oauth2state'] = $provider->getState();
// Redirect the user to the authorization URL.
header('Location: '.$authorizationUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
// State is invalid, possible CSRF attack in progress
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
try {
// Try to get an access token using the authorization code grant.
$accessToken = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code'],
]);
// Use this to interact with an API on the users behalf
echo $token->getToken();
// Use this to get a new access token if the old one expires
echo $token->getRefreshToken();
// Exact timestamp when the access token will expire, and need refreshing
echo $token->getExpires();
// Optional: Now you have a token you can look up a users profile data
// We got an access token, let's now get the owner details
$ownerDetails = $provider->getResourceOwner($token);
// Use these details to create a new profile
printf('Hello %s!', $ownerDetails->getId());
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
// Failed to get the access token or user details.
exit($e->getMessage());
}
}
Refresh tokens are only provided to applications which request offline access. You can specify offline access by setting
the accessType
option in your provider:
$provider = new Generation2\OAuth2\Client\Provider\Generation2Provider([
'clientId' => '{app-id}', // The client ID assigned to you by the provider
'clientSecret' => '{app-secret}', // The client password assigned to you by the provider
'redirectUri' => 'https://example.com/callback-url',
]);
It is important to note that the refresh token is only returned on the first request after this it will be null
. You
should securely store the refresh token when it is returned:
$accessToken = $provider->getAccessToken('authorization_code', [
'code' => $code
]);
// persist the token in a database
$refreshToken = $accessToken->getRefreshToken();
If you ever need to get a new refresh token you can request one by forcing the approval prompt:
$authorizationUrl = $provider->getAuthorizationUrl(['approval_prompt' => 'force']);
Now you have everything you need to refresh an access token using a refresh token:
$provider = new Generation2\OAuth2\Client\Provider\Generation2Provider([
'clientId' => '{app-id}', // The client ID assigned to you by the provider
'clientSecret' => '{app-secret}', // The client password assigned to you by the provider
'redirectUri' => 'https://example.com/callback-url',
]);
$newAccessToken = $provider->getAccessToken('refresh_token', [
'refresh_token' => $oldAccessToken->getRefreshToken()
]);
If needed, you can include an array of scopes when getting the authorization url. Example:
$authorizationUrl = $provider->getAuthorizationUrl([
'scope' => [
'user:id user:email',
]
]);
header('Location: ' . $authorizationUrl);
exit;
./vendor/bin/phpunit
- PHP - Programming Language
- Composer - Dependency Management
- PHPUnit - Testing the code
- Github Actions - Automatic CI (Testing)
- Read the docs - Documentation
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
We use SemVer for versioning. For the versions available, see the tags on this repository.
- Manuele Vaccari - D3strukt0r - Initial work
See also the list of contributors who participated in this project.
This project is licensed under the GNU General Public License v3.0 - see the LICENSE.txt file for details
- Hat tip to anyone whose code was used
- Inspiration
- etc