A spec compliant, secure by default PHP OAuth 2.0 Server


PHP OAuth 2.0 Server

Latest Version Software License Build Status Coverage Status Quality Score Total Downloads

league/oauth2-server is a standards compliant implementation of an OAuth 2.0 authorization server written in PHP which makes working with OAuth 2.0 trivial. You can easily configure an OAuth 2.0 server to protect your API with access tokens, or allow clients to request new access tokens and refresh them.

Out of the box it supports the following grants:

  • Authorization code grant
  • Implicit grant
  • Client credentials grant
  • Resource owner password credentials grant
  • Refresh grant

The following RFCs are implemented:

This library was created by Alex Bilbie. Find him on Twitter at @alexbilbie.


The latest version of this package supports the following versions of PHP:

  • PHP 7.2
  • PHP 7.3
  • PHP 7.4
  • PHP 8.0

The openssl and json extensions are also required.

All HTTP messages passed to the server should be PSR-7 compliant. This ensures interoperability with other packages and frameworks.


composer require league/oauth2-server


The library documentation can be found at https://oauth2.thephpleague.com. You can contribute to the documentation in the gh-pages branch.


The library uses PHPUnit for unit tests.


Continuous Integration

We use Github Actions, Scrutinizer, and StyleCI for continuous integration. Check out our configuration files if you'd like to know more.

Community Integrations


See the project changelog


Contributions are always welcome. Please see CONTRIBUTING.md and CODE_OF_CONDUCT.md for details.


Bugs and feature request are tracked on GitHub.

If you have any questions about OAuth please open a ticket here; please don't email the address below.


If you discover any security related issues, please email [email protected] instead of using the issue tracker.


This package is released under the MIT License. See the bundled LICENSE file for details.


This code is principally developed and maintained by Andy Millington.

Between 2012 and 2017 this library was developed and maintained by Alex Bilbie.

PHP OAuth 2.0 Server is one of many packages provided by The PHP League. To find out more, please visit our website.

Special thanks to all of these awesome contributors.

Additional thanks go to the Mozilla Secure Open Source Fund for funding a security audit of this library.

The initial code was developed as part of the Linkey project which was funded by JISC under the Access and Identity Management programme.

  • Library packed with Codeigniter

    Library packed with Codeigniter

    this is code Ouath2 Controller. I already include "zetacomponents/database": "1.4.6" in composer.json

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    class Oauth2 extends CI_Controller
        public function __construct()
            $this->load->helper(array('url', 'form'));
            // Initiate the request handler which deals with $_GET, $_POST, etc
            $request = new League\OAuth2\Server\Util\Request();
            // Initiate a new database connection
            $db = new League\OAuth2\Server\Storage\PDO\Db('mysql://root:root@localhost/alex_oauth');
            // Create the auth server, the three parameters passed are references
            //  to the storage models
            $this->authserver = new League\OAuth2\Server\Authorization(
                new League\OAuth2\Server\Storage\PDO\Client($db),
                new League\OAuth2\Server\Storage\PDO\Session($db),
                new League\OAuth2\Server\Storage\PDO\Scope($db)
            // Enable the authorization code grant type
            $this->authserver->addGrantType(new League\OAuth2\Server\Grant\AuthCode($this->authserver));
        public function index()
            try {
                // Tell the auth server to check the required parameters are in the
                //  query string
                $params = $this->authserver->getGrantType('authorization_code')->checkAuthoriseParams();
                // Save the verified parameters to the user's session
                $this->session->set_userdata('client_id', $params['client_id']);
                $this->session->set_userdata('client_details', $params['client_details']);
                $this->session->set_userdata('redirect_uri', $params['redirect_uri']);
                $this->session->set_userdata('response_type', $params['response_type']);
                $this->session->set_userdata('scopes', $params['scopes']);
                // Redirect the user to the sign-in route
            } catch (Oauth2\Exception\ClientException $e) {
                echo "error";
                // Throw an error here which says what the problem is with the
                //  auth params
            } catch (Exception $e) {
               // I ALWAYS IN HERE
                echo $e->getMessage();
                // Throw an error here which has caught a non-library specific error
        public function signin()
            // Retrieve the auth params from the user's session
            $params['client_id'] = $this->session->userdata('client_id');
            $params['client_details'] = $this->session->userdata('client_details');
            $params['redirect_uri'] = $this->session->userdata('redirect_uri');
            $params['response_type'] = $this->session->userdata('response_type');
            $params['scopes'] = $this->session->userdata('scopes');
            // Check that the auth params are all present
            foreach ($params as $key=>$value) {
                if ($value == null) {
                    // Throw an error because an auth param is missing - don't
                    //  continue any further
            // Process the sign-in form submission
            if ($this->input->get_post('signin') != null) {
                try {
                    // Get username
                    $u = $this->input->get('username');
                    if ($u == null || trim($u) == '') {
                        throw new Exception('please enter your username.');
                    // Get password
                    $p = $this->input->get('password');
                    if ($p == null || trim($p) == '') {
                        throw new Exception('please enter your password.');
                    // Verify the user's username and password
                    // Set the user's ID to a session
                } catch (Exception $e) {
                    $params['error_message'] = $e->getMessage();
            // Get the user's ID from their session
            $params['user_id'] = $this->session->userdata('user_id');
            // User is signed in
            if ($params['user_id'] != null) {
                // Redirect the user to /oauth/authorise route
            // User is not signed in, show the sign-in form
            else {
                echo "login form";
    opened by fahmiardi 30
  • Put and Delete

    Put and Delete

    I get the following errors when trying to use both a PUT and DELETE request.

    Call to undefined method League\OAuth2\Server\Util\Request::DELETE() Call to undefined method League\OAuth2\Server\Util\Request::PUT()

    This happens if i pass the access_token as a parameter.

    If it's an authorization header it's fine.

    opened by sicsol 26
  • Documentation


    Now that v4 has been merged into develop branch I can work on the documentation.

    This issue is for tracking new documentation which will be located at http://oauth2.thephpleague.com/


    • [x] Resource server
    • [x] Auth code grant
    • [x] Client credentials grant
    • [x] Password grant
    • [x] Refresh token
    • [x] Creating your own grants
    • [x] Subscribing to events
    • [x] Creating your own token identifier generator
    • [ ] Creating your own token types
    • [ ] Integration with frameworks
    • [ ] Upgrading from v3
    opened by alexbilbie 23
  • BC break when extending BearerTokenResponse

    BC break when extending BearerTokenResponse

    My application just broke down when upgrading to 7.3.0, working fine still when downgrading to 7.2.0.

    I'm using the following override in my custom OAuth2Server class to customize the response type:

         * {@inheritdoc}
        protected function getResponseType()
            $this->responseType = new ExtendedBearerTokenResponse(...someparameters);
            return parent::getResponseType();

    The extended response class overrides the default BearerTokenResponse in getExtraParams to add some extra properties to the token. This method is apparently not called anymore, or ignored, as the tokens no longer contain the extra properties.

    Have an appointment in 5 minutes so no time to debug further right now, but posting this already hoping you may have an idea what's causing this and issue a fix before I can investigate deeper tomorrow.

    opened by curry684 22
  • Resource server errors

    Resource server errors

    Copies helper methods for exception handling from the Authorization server into the Resource server to allow for implementing RFC 6750, section 3.1:

    • getExceptionType
    • getExceptionMessage
    • getExceptionHttpHeaders

    Adds $required parameter to hasScope to trigger exceptions when scopes are missing from the session.

    Adds two new exceptions, MissingAccessToken and InsufficientScope to differentiate between the different error responses from the resource server.

    Tests updated and new tests written to complete code coverage.

    opened by shadowhand 22
  • Question: Implicit grant

    Question: Implicit grant

    On the implicit grant, how do I use newAuthoriseRequest() and checkAuthoriseParams() which exist only in AuthCode? I see only completeFlow() on the Implicit object.

    As of now I have implemented the Implicit flow using the outdated AuthCode tutorial, so my last /authorise route actually takes the generated auth code and makes an access token out of it, which is returned to the user, instead of returning the auth code.

    Right now, using the altered AuthCode grant for Implicit, my /authorise route looks like this:

    $app->post('/authorise', function() use ($server, $app) {
            // Check the auth params are in the session
            if ( ! isset($_SESSION['authParams']))
                    throw new Exception('Missing auth parameters');
            $params = $_SESSION['authParams'];
            // Check the user is signed in
            if ( ! isset($params['user_id']))
            // If the user approves the client then generate an authoriztion code
            if (isset($_POST['approve']))
                    $authCode = $server->getGrantType("authorization_code")->newAuthoriseRequest('user', $params['user_id'], $params);
                    // echo '<p>The user authorised a request and so would be redirected back to the client...</p>';   
                    //So far this is Authorisation Grant. Now we want to make it Implicit and return an access token staight ahead.
                    header('Content-type: application/javascript');
                    try {
                        $params["grant_type"] = "authorization_code";
                        $params["code"] = $authCode;
                        foreach ($params['client_details'] as $key => &$clientParam){
                            $params[$key] = $clientParam;
                        $acToken = $server->issueAccessToken($params);
                        echo json_encode($acToken);
                    } catch (Exception $e) {
                    // Show an error message
                    echo json_encode(array('error' => $e->getMessage(), 'error_code' => $e->getCode()));
            // The user denied the request so send them back to the client with an error
            elseif (isset($_POST['deny']))
                    // echo '<p>The user denied the request and so would be redirected back to the client...</p>';
                    // echo League\OAuth2\Server\Util\RedirectUri::make($params['redirect_uri'], array(
                    //         'error' => 'access_denied',
                    //         'error_message' => $server::getExceptionMessage('access_denied'),
                    //         'state'        => $params['state']
                    // ));
                echo json_encode(array( //error response as valid json
                             'error' => 'access_denied',
                             'error_message' => $server::getExceptionMessage('access_denied'),
                             'state'        => $params['state'])
    opened by origal 21
  • Old refresh token should not be IMMEDIATELY revoked

    Old refresh token should not be IMMEDIATELY revoked

    From RFC 6749 Section 6 - Refreshing an Access Token:

    The authorization server MAY issue a new refresh token, .... The authorization server MAY revoke the old refresh token after issuing a new refresh token to the client.

    Here is 2 points I have in mind:

    1. Based on the use cases I am familiar with, the only time the authorization server may decide not to issue a new refresh token is when it is sure the current refresh token is not going to be expired sooner than the next refresh token request - AKA NEVER.
    2. It is a good idea that the authorization server revoke the old refresh token, but it may be better to think about the chance of network failure as well. Let say a client has a token granted via password, and now, it has to request for a refresh token. The request will be accepted by the server, but the response is not reached backed to the client. Now the client should ask for the user's password, only because of a temporary network error.

    So I propose that the server should revoke the old refresh token only after it is sure the client has the new one. To make sure about it the server may do as followed:

    1. Revoke the old refresh token the first time the new access/refresh token is used.
    2. Revoke the new refresh token, if the old but un-revoked refresh token is used again, which indicates that the new refresh token is never delivered to the client.
    opened by halaei 19
  • OAuth2 Spec interpretation: finalizeScopes()

    OAuth2 Spec interpretation: finalizeScopes()

    The OAuth2 spec (https://tools.ietf.org/html/rfc6749#section-6) states:

             OPTIONAL.  The scope of the access request as described by
             Section 3.3.  The requested scope MUST NOT include any scope
             not originally granted by the resource owner, and if omitted is
             treated as equal to the scope originally granted by the
             resource owner.

    This library however interprets that to say: 'the scopes that were originally in the access token', but the spec only says: 'scopes granted by the resource owner'. Therefore, if I show the resource owner a prompt to approve for instance the test and demo scopes, and they are approved, but I remove demo in the finalizeScopes() call, because this scope is not available (right now) for the resource owner to grant, it will never be included after refreshing, even if it becomes available again lateron, while the user did grant permission.

    Use case

    In an API I'm building OAuth2 scopes are used for permissions. People can request data from an endpoint, but that endpoint may be temporarily disabled for some users during data updates, or at the end of the year, if the data gets updated for the next year.

    Therefore, applications can request a scope for that endpoint, but they may temporarily not be granted the scope. I, however, don't want to force them to login again if the scope becomes available again, because the resource owner did grant permission after all. It should transparently be added back in, as the resource owner would expect. Scopes not allowed during the initial call, whether they were available or not, were never approved, and therefore should, as the spec says, never be included, even if their availability changes.

    Improvement Idea 
    opened by christiaangoossens 18
  • Removed chmod from CryptKey and add toggle to disable checking

    Removed chmod from CryptKey and add toggle to disable checking

    First of all, please do not touch my files... I do not think it's the responsibility of a package to set file permissions. It is the responsibility of your deployment pipeline or developers themselves.

    While I appreciate the intent that was done in 2f8de3d2302beb490abb9475cf426148801c25c4. This is breaking for us in both our development and our production environments. And according to #760 for more people.

    With this PR I would like to propose two things:

    • First and foremost, remove any code that modifies files. However, do trigger a USER_NOTICE when not set to 600.
    • Option to skip the check. This can be useful for DEV environments.

    A bit of context for our case:

    Our PROD setup is as follows: We have 4 users: deploy, worker, scheduler and apache. All four are part of the deployment group. So our code is chowned as deploy:deployment. So while 600 might seems like a good assumption, it will prevent our apache user from reading the key, thus breaking the web requests.

    Our DEV setup is a bit different: We have our own users, yannickl88 in my case, and www-data for the web user. Files are chmodded 666 so both users can read everything. (we have a umask 0000 everywhere). While not the best setup, it's just development. In this case 660 is even not enough, but a warning would be justified. However, we would like to silence this in our DEV environment since Symfony converts the USER_NOTICE to an exception, making the lib unusable.

    opened by yannickl88 18
  • "Ensure the server is the exclusive owner of the key" is wrong

    the implementation is wrong if ($keyPathPerms !== '600') {

    you cant say that this is the perfect permission. you might have set up the file with permission to the group

    which you then have '660'

    Improvement Idea 
    opened by gemal 18
  • Cannot use the client credentials without any redirect URI

    Cannot use the client credentials without any redirect URI

    AFAIK when using only the client credentials grant, one can use a client without any redirect URI (as it's not used anywhere in this grant).

    Change introduced in #1140 makes it impossible to use such client.

    Discussion Spec Compliance 
    opened by magnetik 16
  • Zapier not refreshing token

    Zapier not refreshing token

    Hello! I'm trying to implement Zapier as a client for a php slim app. Everything seems to be working great (even authorization, returning the correct data on custom endpoints) but the token expires after an hour and after that, zapier requires me to re-authorize the app, including opening the scopes window. By following the documentation, it seems that both routes (request access token and refresh) seem to be the same, so I've pointed both settings to the same route. Am I missing something here? Thank you for your help!

    opened by ignacionelson 2
  • Update phpunit/phpunit requirement from ^8.5.13 to ^9.5.27

    Update phpunit/phpunit requirement from ^8.5.13 to ^9.5.27

    Updates the requirements on phpunit/phpunit to permit the latest version.


    Sourced from phpunit/phpunit's changelog.

    [9.5.27] - 2022-MM-DD


    • #5113: PHP error instead of PHPUnit error when trying to create test double for readonly class

    [9.5.26] - 2022-10-28


    • #5076: Test Runner does not warn about conflicting options

    [9.5.25] - 2022-09-25


    • #5042: Support Disjunctive Normal Form types


    • #4966: TestCase::assertSame() (and related exact comparisons) must compare float exactly

    [9.5.24] - 2022-08-30


    • #4931: Support null and false as stand-alone types
    • #4955: Support true as stand-alone type


    • #4913: Failed assert() should show a backtrace
    • #5012: Memory leak in ExceptionWrapper

    [9.5.23] - 2022-08-22


    • #5033: Do not depend on phpspec/prophecy

    [9.5.22] - 2022-08-20


    • #5015: Ukraine banner unreadable on black background
    • #5020: PHPUnit 9 breaks loading of PSR-0/PEAR style classes
    • #5022: ExcludeList::addDirectory() does not work correctly

    [9.5.21] - 2022-06-19

    ... (truncated)

    • a2bc7ff Prepare release
    • 1b09a9a Exclude source file with PHP 8.2 syntax
    • ac259bc Update Psalm baseline
    • 9e0968d Update ChangeLog
    • 8635ff9 Skip test on PHP < 8.2
    • faa1515 Implement logic to blocks readonly classes to be doubled.
    • 5c6e811 Merge branch '8.5' into 9.5
    • cc19735 Update tools
    • c5d3542 Assert that we have a DOMElement here
    • a653302 Document collected/iterated type using Psalm template
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.

    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    opened by dependabot[bot] 0
  • Add support for RFC8693 - token exchange

    Add support for RFC8693 - token exchange

    Token exchange is a new grant type defined by the IETF providing support for impersonation and delegation scenarios, such as the following:

    Illustration by Scott Brady Illustration by Scott Brady

    In a nutshell, the grant type involves the following steps:

    Exchanging a token

    This uses a new grant type of urn:ietf:params:oauth:grant-type:token-exchange and allows the requester to identify and authenticate themselves. Here, API1 is swapping the token it received for access to API2.

    The subject token is the token sent by the client application, delegated by the user. Since this token was delegated using OAuth, the subject token type is urn:ietf:params:oauth:token-type:access_token (an access token).

    POST /token
    Host: auth.example.com
    Content-Type: application/x-www-form-urlencoded

    Token exchange response

    The token response for token exchange is then slightly different than what you are used to:

    HTTP/1.1 200 OK
    Content-Type: application/json
    Cache-Control: no-cache, no-store
      "access_token": "lt6QCYJ58k44GRoCwwBPcFDPzYzHdGClhM9qCuh39DIL",
      "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
      "token_type": "Bearer",
      "expires_in": 60

    The issued_token_type tells API1 (now acting as a client application) that it has sent back an access token. This allows API1 to understand how to use the token it has just received. In this case, it’s an access token that it can use to access a protected resource (API2).

    The access token

    The initial token was delegated by user, to the client application app, and you’re still acting on their behalf. But, by using the act claim set, you can show that api1 is the current actor. At the very least, this would be valuable for audit trials.

      "iss": "https://auth.example.com",
      "sub": "123xyz_user",
      "client_id": "app",
      "aud": "api2",
      "scope": "api2",
      "act": {
        "client_id": "api1"
      "exp": 1443904177,
      "nbf": 1443904077

    In addition to the act claim type, the Authorized Actor claim type (may_act) allows you to explicitly state who is allowed to act on someone’s behalf. For instance, if you wanted to explicitly state that api1 is authorized to act on app’s behalf, then the original access token API1 receives, may look like:

      "iss": "https://auth.example.com",
      "sub": "123xyz_user",
      "client_id": "app",
      "aud": "api1",
      "scope": "api1",
      "may_act": {
        "client_id": "api1"
      "exp": 1443904177,
      "nbf": 1443904077

    Now, when validating a token exchange request, the authorization server can check that the subject token has this may_act and that it includes the ID of the token exchange requester.

    Use Cases

    Token Exchange is great for API-to-API delegation, stuff like customer service acting on behalf of a customer, and preserving clear audit trails across services, as well as checking that zero trust checkbox on your compliance terms thoroughly.

    I would love to see token exchange being implemented in oauth2-server, and subsequently in Laravel Passport. I have quite a bit of experience working with OAuth in PHP and would like to contribute to this, if there's any interest in implementing that grant type.

    Future Version Improvement Idea 
    opened by Radiergummi 3
  • Update league/event requirement from ^2.2 to ^3.0

    Update league/event requirement from ^2.2 to ^3.0

    Updates the requirements on league/event to permit the latest version.


    Sourced from league/event's changelog.

    3.0.2 - 29-10-2022


    • Reduce complexity of removing one-time listeners (#102)

    3.0.1 - 28-10-2022


    • Ensure one-time-listener is removed from the sorted list of listeners in the prioritized sub-class

    3.0.0 - 29-09-2020

    • PSR-14 is now supported.
    • Classes and interfaces renamed to match PSR terminology.

    2.2.0 - 2018-11-26

    • Buffered event emitter was added.

    2.1.2 - 2015-05-21


    • Event emitting now respects the order in which the listeners were added in addition to priority.

    2.1.1 - 2015-03-30


    • Emitter::emitBatch now uses a foreach instead of array map to allow better exception handling.

    2.1.0 - 2015-02-12


    • EmitterAwareInterface: an interface to be EmitterInterface aware.
    • EmitterAwareTrait: a default implementation to EmitterAwareInterface


    • EmitterTrait: The EmitterAware interface was extracted from this, which it now uses.

    2.0.0 - 2014-12-09


    • EventInterface: an interface is derived from the AbstractEvent class to allow more flexible type hinting and custom implementations. All the code expecting an AbstractEvent now expect an EventInterface implementation, however AbstractEvent covers the most use cases.
    • Event::named: named construtor to create string based events

    ... (truncated)

    • 221867a Correct release date
    • c4343b1 Reformat PR and prep for release.
    • ed612ec Merge pull request #102 from wenbinye/fix-event-listeners
    • 9ef6813 Remove state property in PrioritizedListenersForEvent
    • a9764f4 Prep changelog
    • 7f5f770 Fix CS of PR
    • e1fc276 Merge pull request #101 from wenbinye/fix-onetimelistener
    • 6fbbc2a Fix PrioritizedListenersForEvent when OneTimeListener added
    • 6d6d88d Pre-release changelog
    • 36e003a Buffered event dispatcher returns dispatched events when dispatching the buffer.
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.

    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    opened by dependabot[bot] 0
  • [UPGRADE] Upgrade league/event to version 3.

    [UPGRADE] Upgrade league/event to version 3.

    This PR upgrades League\Event to version 3 while making the upgrade process smooth. I've added compatibility layers in to make the upgrade process smooth for users. Still, because return types are different, these changes are technically BC breaks.

    opened by frankdejonge 1
  • 8.3.6(Nov 14, 2022)

  • 8.3.5(May 12, 2022)

  • 8.3.4(Apr 7, 2022)

  • 8.3.3(Oct 11, 2021)

  • 8.3.2(Jul 27, 2021)


    • Conditionally support the StrictValidAt() method in lcobucci/jwt so we can use version 4.1.x or greater of the library (PR #1236)
    • When providing invalid credentials, the library now responds with the error message The user credentials were incorrect (PR #1230)
    • Keys are always stored in memory now and are not written to a file in the /tmp directory (PR #1180)
    • The regex for matching the bearer token has been simplified (PR #1238)
    Source code(tar.gz)
    Source code(zip)
  • 8.3.1(Jun 4, 2021)

  • 8.3.0(Jun 3, 2021)


    • The server will now validate redirect uris according to rfc8252 (PR #1203)
    • Events emitted now include the refresh token and access token payloads (PR #1211)
    • Use the revokeRefreshTokens() function to decide whether refresh tokens are revoked or not upon use (PR #1189)


    • Keys are now validated using openssl_pkey_get_private() and openssl_pkey_get_public()` instead of regex matching (PR #1215)


    • The server will now only recognise and handle an authorization header if the value of the header is non-empty. This is to circumvent issues where some common frameworks set this header even if no value is present (PR #1170)
    • Added type validation for redirect uri, client ID, client secret, scopes, auth code, state, username, and password inputs (PR #1210)
    • Allow scope "0" to be used. Previously this was removed from a request because it failed an empty() check (PR #1181)
    Source code(tar.gz)
    Source code(zip)
  • 8.2.4(Dec 10, 2020)

  • 8.2.3(Dec 3, 2020)

  • 8.2.2(Nov 30, 2020)

  • 8.2.1(Nov 26, 2020)

  • 8.2.0(Nov 25, 2020)


    • Add a getRedirectUri function to the OAuthServerException class (PR #1123)
    • Support for PHP 8.0 (PR #1146)


    • Removed support for PHP 7.2 (PR #1146)


    • Fix typo in parameter hint. code_challenged changed to code_challenge. Thrown by Auth Code Grant when the code challenge does not match the regex. (PR #1130)
    • Undefined offset was returned when no client redirect URI was set. Now throw an invalidClient exception if no redirect URI is set against a client (PR #1140)
    Source code(tar.gz)
    Source code(zip)
  • 8.1.1(Jul 1, 2020)


    • If you provide a valid redirect_uri with the auth code grant and an invalid scope, the server will use the given redirect_uri instead of the default client redirect uri (PR #1126)
    Source code(tar.gz)
    Source code(zip)
  • 8.1.0(Apr 29, 2020)


    • Added support for PHP 7.4 (PR #1075)


    • If an error is encountered when running preg_match() to validate an RSA key, the server will now throw a RuntimeException (PR #1047)
    • Replaced deprecated methods with recommended ones when using Lcobucci\JWT\Builder to build a JWT token. (PR #1060)
    • When storing a key, we no longer touch the file before writing it as this is an unnecessary step (PR #1064)
    • Prefix native PHP functions in namespaces with backslashes for micro-optimisations (PR #1071)


    • Support for PHP 7.1 (PR #1075)


    • Clients are now explicitly prevented from using the Client Credentials grant unless they are confidential to conform with the OAuth2 spec (PR #1035)
    • Abstract method getIdentifier() added to AccessTokenTrait. The trait cannot be used without the getIdentifier() method being defined (PR #1051)
    • An exception is now thrown if a refresh token is accidentally sent in place of an authorization code when using the Auth Code Grant (PR #1057)
    • Can now send access token request without being forced to specify a redirect URI (PR #1096)
    • In the BearerTokenValidator, if an implementation is using PDO, there is a possibility that a RuntimeException will be thrown when checking if an access token is revoked. This scenario no longer incorrectly issues an exception with a hint mentioning an issue with JSON decoding. (PR #1107)
    Source code(tar.gz)
    Source code(zip)
  • 8.0.0(Jul 13, 2019)


    • Flag, requireCodeChallengeForPublicClients, used to reject public clients that do not provide a code challenge for the Auth Code Grant; use AuthCodeGrant::disableRequireCodeCallengeForPublicClients() to turn off this requirement (PR #938)
    • Public clients can now use the Auth Code Grant (PR #938)
    • isConfidential getter added to ClientEntity to identify type of client (PR #938)
    • Function validateClient() added to validate clients which was previously performed by the getClientEntity() function (PR #938)
    • Add a new function to the AbstractGrant class called getClientEntityOrFail(). This is a wrapper around the getClientEntity() function that ensures we emit and throw an exception if the repo doesn't return a client entity. (PR #1010)


    • Replace convertToJWT() interface with a more generic __toString() to improve extensibility; AccessTokenEntityInterface now requires setPrivateKey(CryptKey $privateKey) so __toString() has everything it needs to work (PR #874)
    • The invalidClient() function accepts a PSR-7 compliant $serverRequest argument to avoid accessing the $_SERVER global variable and improve testing (PR #899)
    • issueAccessToken() in the Abstract Grant no longer sets access token client, user ID or scopes. These values should already have been set when calling getNewToken() (PR #919)
    • No longer need to enable PKCE with enableCodeExchangeProof flag. Any client sending a code challenge will initiate PKCE checks. (PR #938)
    • Function getClientEntity() no longer performs client validation (PR #938)
    • Password Grant now returns an invalid_grant error instead of invalid_credentials if a user cannot be validated (PR #967)
    • Use DateTimeImmutable() instead of DateTime(), time() instead of (new DateTime())->getTimeStamp(), and DateTime::getTimeStamp() instead of DateTime::format('U') (PR #963)


    • enableCodeExchangeProof flag (PR #938)
    • Support for PHP 7.0 (PR #1014)
    • Remove JTI claim from JWT header (PR #1031)
    Source code(tar.gz)
    Source code(zip)
  • 7.4.0(May 5, 2019)

  • 7.3.3(Mar 29, 2019)


    • Added error_description to the error payload to improve standards compliance. The contents of this are copied from the existing message value. (PR #1006)


    • Error payload will not issue message value in the next major release (PR #1006)
    Source code(tar.gz)
    Source code(zip)
  • 7.3.2(Nov 21, 2018)

  • 7.3.1(Nov 15, 2018)


    • Fix issue with previous release where interface had changed for the AuthorizationServer. Reverted to the previous interface while maintaining functionality changes (PR #970)
    Source code(tar.gz)
    Source code(zip)
  • 7.3.0(Nov 13, 2018)


    • Moved the finalizeScopes() call from validateAuthorizationRequest method to the completeAuthorizationRequest method so it is called just before the access token is issued (PR #923)


    • Added a ScopeTrait to provide an implementation for jsonSerialize (PR #952)
    • Ability to nest exceptions (PR #965)


    • Fix issue where AuthorizationServer is not stateless as ResponseType could store state of a previous request (PR #960)
    Source code(tar.gz)
    Source code(zip)
  • 7.2.0(Jun 23, 2018)


    • Added newvalidateRedirectUri method AbstractGrant to remove three instances of code duplication (PR #912)
    • Allow 640 as a crypt key file permission (PR #917)


    • Function hasRedirect() added to OAuthServerException (PR #703)


    • Catch and handle BadMethodCallException from the verify() method of the JWT token in the validateAuthorization method (PR #904)
    Source code(tar.gz)
    Source code(zip)
  • 4.1.7(Jun 23, 2018)

  • 7.1.1(May 21, 2018)


    • No longer set a WWW-Authenticate header for invalid clients if the client did not send an Authorization header in the original request (PR #902)
    Source code(tar.gz)
    Source code(zip)
  • 7.1.0(Apr 22, 2018)


    • Changed hint for unsupportedGrantType exception so it no longer references the grant type parameter which isn't always expected (PR #893)
    • Upgrade PHPStan checks to level 7 (PR #856)


    • Added event emitters for issued access and refresh tokens (PR #860)
    • Can now use Defuse\Crypto\Key for encryption/decryption of keys which is faster than the Cryto class (PR #812)
    Source code(tar.gz)
    Source code(zip)
  • 6.1.1(Dec 23, 2017)

  • 6.1.0(Dec 23, 2017)

    • Changed the token type issued by the Implicit Grant to be Bearer instead of bearer. (PR #724)
    • Replaced call to array_key_exists() with the faster isset() on the Implicit Grant. (PR #749)
    • Allow specification of query delimiter character in the Password Grant (PR #801)
    • Add Zend Diactoros library dependency to examples (PR #678)
    • Can set default scope for the authorization endpoint. If no scope is passed during an authorization request, the default scope will be used if set. If not, the server will issue an invalid scope exception (PR #811)
    • Added validation for redirect URIs on the authorization end point to ensure exactly one redirection URI has been passed (PR #573)
    Source code(tar.gz)
    Source code(zip)
  • 5.1.6(Nov 29, 2017)

  • 6.0.2(Aug 3, 2017)

    • An invalid refresh token that can't be decrypted now returns a HTTP 401 error instead of HTTP 400 (Issue #759)
    • Removed chmod from CryptKey and add toggle to disable checking (Issue #776)
    • Fixes invalid code challenge method payload key name (Issue #777)
    Source code(tar.gz)
    Source code(zip)
  • 5.1.5(Jul 11, 2017)

    To address feedback from the security release the following two changes have been made:

    • If an RSA key cannot be chmod'ed to 600 then it will now throw a E_USER_NOTICE instead of an exception.
    • Not using the new encryption key method on AuthorizationServer will set throw an E_USER_DEPRECATED message instead of an error.
    Source code(tar.gz)
    Source code(zip)
The League of Extraordinary Packages
A group of developers who have banded together to build solid, well tested PHP packages using modern coding standards.
The League of Extraordinary Packages
PHPoAuthLib provides oAuth support in PHP 7.2+ and is very easy to integrate with any project which requires an oAuth client.

PHPoAuthLib NOTE: I'm looking for someone who could help to maintain this package alongside me, just because I don't have a ton of time to devote to i

David Desberg 1.1k Dec 27, 2022
Laravel wrapper around OAuth 1 & OAuth 2 libraries.

Introduction Laravel Socialite provides an expressive, fluent interface to OAuth authentication with Facebook, Twitter, Google, LinkedIn, GitHub, GitL

The Laravel Framework 5.2k Dec 27, 2022
EAuth extension allows to authenticate users by the OpenID, OAuth 1.0 and OAuth 2.0 providers

EAuth extension allows to authenticate users with accounts on other websites. Supported protocols: OpenID, OAuth 1.0 and OAuth 2.0.

Maxim Zemskov 330 Jun 3, 2022
The Salla OAuth Client library is designed to provide client applications with secure delegated access to Salla Merchant stores.

Salla Provider for OAuth 2.0 Client This package provides Salla OAuth 2.0 support for the PHP League's OAuth 2.0 Client. To use this package, it will

Salla 14 Nov 27, 2022
Kaiju is an open source verification bot based on Discord's OAuth written in C# and PHP, with the functionality of being able to integrate the user to a new server in case yours is suspended.

What is Kaiju? Kaiju is an open source verification bot for Discord servers, based on OAuth and with permission for the server owner, to be able to mi

in the space 10 Nov 20, 2022
Symfony bundle which provides OAuth 2.0 authorization/resource server capabilities

Symfony bundle which provides OAuth 2.0 authorization/resource server capabilities. The authorization and resource server actors are implemented using the thephpleague/oauth2-server library.

Trikoder 253 Dec 21, 2022
OAuth server implementation for WP API

WP REST API - OAuth 1.0a Server Connect applications to your WordPress site without ever giving away your password. This plugin uses the OAuth 1.0a pr

WordPress REST API Team 314 Dec 10, 2022
Painless OAuth 2.0 Server for CodeIgniter 4 🔥

Inspired from the Norse mythology, Heimdallr, modernly anglicized as Heimdall is the gatekeeper of Bifröst, the rainbow road connecting Midgard, realm

Ezra Lazuardy 37 Nov 12, 2022
PHP 5.3+ oAuth 1/2 Client Library

PHPoAuthLib NOTE: I'm looking for someone who could help to maintain this package alongside me, just because I don't have a ton of time to devote to i

David Desberg 1.1k Dec 27, 2022
The first PHP Library to support OAuth for Twitter's REST API.

THIS IS AN MODIFIED VERSION OF ABRAHAMS TWITTER OAUTH CLASS The directories are structured and the class uses PHP5.3 namespaces. Api.php has a new

Ruud Kamphuis 51 Feb 11, 2021
The most popular PHP library for use with the Twitter OAuth REST API.

TwitterOAuth The most popular PHP library for Twitter's OAuth REST API. See documentation at https://twitteroauth.com. PHP versions listed as "active

Abraham Williams 4.2k Dec 23, 2022
Twitter OAuth API for PHP 5.3+

README The Wid'op OAuth library is a modern PHP 5.3+ API allowing you to easily obtain a Twitter access token. For now, it supports OAuth Web & Applic

Wid'op 8 Dec 11, 2020
Easy integration with OAuth 2.0 service providers.

OAuth 2.0 Client This package provides a base for integrating with OAuth 2.0 service providers. The OAuth 2.0 login flow, seen commonly around the web

The League of Extraordinary Packages 3.4k Dec 31, 2022
OAuth 1 Client

OAuth 1.0 Client OAuth 1 Client is an OAuth RFC 5849 standards-compliant library for authenticating against OAuth 1 servers. It has built in support f

The League of Extraordinary Packages 907 Dec 16, 2022
OAuth client integration for Symfony. Supports both OAuth1.0a and OAuth2.

HWIOAuthBundle The HWIOAuthBundle adds support for authenticating users via OAuth1.0a or OAuth2 in Symfony. Note: this bundle adds easy way to impleme

Hardware Info 2.2k Dec 30, 2022
An OAuth 2.0 bridge for Laravel and Lumen [DEPRECATED FOR LARAVEL 5.3+]

OAuth 2.0 Server for Laravel (deprecated for Laravel 5.3+) Note: This package is no longer maintaned for Laravel 5.3+ since Laravel now features the P

Luca Degasperi 2.4k Jan 6, 2023
This module is intended to provide oauth authentication to freescout.

OAuth FreeScout This module is intended to provide oauth authentication to freescout. Module was tested on keycloak oauth provider with confidential o

Michael Bolsunovskyi 9 Dec 21, 2022
A Laravel 5 package for OAuth Social Login/Register implementation using Laravel socialite and (optionally) AdminLTE Laravel package

laravel-social A Laravel 5 package for OAuth Social Login/Register implementation using Laravel socialite and (optionally) AdminLTE Laravel package. I

Sergi Tur Badenas 42 Nov 29, 2022
OAuth Service Provider for Laravel 4

OAuth wrapper for Laravel 4 oauth-4-laravel is a simple laravel 4 service provider (wrapper) for Lusitanian/PHPoAuthLib which provides oAuth support i

Dariusz Prząda 693 Sep 5, 2022