PHPackages                             zfr/zfr-oauth2-server - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. zfr/zfr-oauth2-server

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

zfr/zfr-oauth2-server
=====================

PHP library to create an OAuth 2 server

0.10.0(3y ago)3640.9k↓33.3%13[6 issues](https://github.com/zf-fr/zfr-oauth2-server/issues)2MITPHPPHP ^7.4 || ^8.0

Since Mar 30Pushed 3y ago8 watchersCompare

[ Source](https://github.com/zf-fr/zfr-oauth2-server)[ Packagist](https://packagist.org/packages/zfr/zfr-oauth2-server)[ Docs](http://www.github.com/zf-fr/zfr-oauth2-server)[ RSS](/packages/zfr-zfr-oauth2-server/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (17)Used By (2)

ZfrOAuth2Server
===============

[](#zfroauth2server)

[![Continuous Integration](https://github.com/zf-fr/zfr-oauth2-server/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/zf-fr/zfr-oauth2-server/actions/workflows/continuous-integration.yml)[![Latest Stable Version](https://camo.githubusercontent.com/25ec5b536b08a98e7695f0f743ca2446106d1a4547ae05097d1faf50456bbea7/68747470733a2f2f706f7365722e707567782e6f72672f7a66722f7a66722d6f61757468322d7365727665722f762f737461626c652e706e67)](https://packagist.org/packages/zfr/zfr-oauth2-server)[![Coverage Status](https://camo.githubusercontent.com/17c606933005b67840042fdd94b773014b645acdc2e4e500886799ddf004f7cd/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f7a662d66722f7a66722d6f61757468322d7365727665722f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/zf-fr/zfr-oauth2-server?branch=master)[![Total Downloads](https://camo.githubusercontent.com/b62054ab40a425737ac22f858970645d9170192834077a976c2c8a79c956f58d/68747470733a2f2f706f7365722e707567782e6f72672f7a66722f7a66722d6f61757468322d7365727665722f646f776e6c6f6164732e706e67)](https://packagist.org/packages/zfr/zfr-oauth2-server)[![Gitter](https://camo.githubusercontent.com/abe08b740a4156153736f791393ec4da6619c4be73212e75769f52edacc0e2b5/68747470733a2f2f6261646765732e6769747465722e696d2f4a6f696e253230436861742e737667)](https://gitter.im/prolic/zfr-oauth2-server)

ZfrOAuth2Server is a PHP library that implements the OAuth 2 specification. It's main goal is to be a clean, PHP 7.0+ library that aims to be used with any persistence layer of choice. It is compatible with [PSR-7](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-7-http-message.md) request and responses which makes it possible to use with any framework compatible with PSR-7.

Currently, ZfrOAuth2Server does not implement the whole specification (implicit grant is missing), so you are encouraged to have a look at the doc if ZfrOAuth2Server can be used in your application.

However, it implements the additional [token revocation](https://tools.ietf.org/html/rfc7009) specification.

Here are other OAuth2 library you can use:

- [OAuth2 Server from PHP-League](https://github.com/php-loep/oauth2-server)
- [OAuth2 Server from Brent Shaffer](https://github.com/bshaffer/oauth2-server-php)

Requirements
------------

[](#requirements)

- PHP 7.4 or higher

To-do
-----

[](#to-do)

- Write documentation
- Security audit
- Review of the whole spec
- Testing the authorization server more extensively
- Add implicit grant

Versioning note
---------------

[](#versioning-note)

Please note that until we reach 1.0, we **WILL NOT** follow semantic version. This means that BC can occur between 0.1.x and 0.2.x releases.

The current pre release of a completely rewritten version, is it not copatible with the previous implementation - which is considered EOL - see the [legacy-0.7](https://github.com/zf-fr/zfr-oauth2-server/tree/legacy-0.7) branch.

See the [CHANGELOG](CHANGELOG.md)

Installation
------------

[](#installation)

use Composer to install:

```
php composer.phar require zfr/zfr-oauth2-server:^0.9-beta
```

Support
-------

[](#support)

- File issues at .
- Say hello in our [gitter](https://gitter.im/prolic/zfr-oauth2-server) chat.

Configuration
-------------

[](#configuration)

Several Apache modules will strip HTTP authorization headers such as `Authorization` to try to enhance security by preventing scripts from seeing sensitive information unless the developer explicitly enables this.

Many of these modules will allow such headers if you simply add the following line to .htaccess (or the vhost directory directive).

```
CGIPassAuth on

```

since: [Apache 2.4.13](https://httpd.apache.org/docs/trunk/mod/core.html#cgipassauth)

Documentation
-------------

[](#documentation)

ZfrOAuth2Server is based on the [RFC 6749](http://tools.ietf.org/html/rfc6749) documentation.

### Why use OAuth2?

[](#why-use-oauth2)

OAuth2 is an authentication/authorization system that allows that can be used to:

- Implement a stateless authentication mechanism (useful for API)
- Allow third-party to connect to your application securely
- Securing your application through the use of scopes

OAuth2 is a dense, extensible specification that can be used for a wide number of use-cases. As of today, ZfrOAuth2Server implements three of the four official grants: AuthorizationGrant, ClientCredentialsGrant, PasswordGrant. Additionally a RefreshTokenGrant is provided to obtain new access tokens. ImplicitGrant and JWTTokens are forthcoming (help wanted).

### How OAuth2 works?

[](#how-oauth2-works)

This documentation does not aim to explain in details how OAuth2 work. Here is [a nice resource](http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified) you can read. However, here is the basic idea of how OAuth2 works:

1. A resource owner (your JavaScript API, your mobile application...) asks for a so-called "access token" to an authorization server. There are several strategies that depends on the use-case. Those strategies are called "grants". For instance, the "password grant" assumes that the resource owner sends its username/password. In all cases, your authorization server responds with an access token (and an optional refresh token).
2. The client sends this access token to each request that is made to your API. It is used by a "resource server" to map this access token to a user in your system.

Choosing the grant type depends on your application. Here are a few hints about which one to choose:

- If you are the only consumer of your API (for instance, your JavaScript application make calls to your API), you should use the "password grant". Because you trust your application, it is not a problem to send username/password.
- If you want a third-party code to connect to your API, and that you are sure that this third-party can keep secrets (this means the client is not a JavaScript API, or a mobile application): you can use the client credentials grant.
- If you want third-party code to connect to your API, and that those third-party applications cannot keep secret (think about an unofficial Twitter client that connect to your Twitter account, for instance), you should use the authorization grant.

### Using the authorization server

[](#using-the-authorization-server)

The authorization server goal is to accept a request, and generate token. An authorization server can deny a request (for instance, if parameters are missing, or if username/password are incorrect).

To use an authorization server, you must first decide which grant you want to support. Some applications should only support one type of grant, others may support all of the available grant. This is completely up to you, and you should have a solid understanding of all those grants first. For instance, here is how you would create an authorization server that support the authorization only:

```
$authTokenService    = new TokenService($objectManager, $authTokenRepository, $scopeRepository);
$accessTokenService  = new TokenService($objectManager, $accessTokenRepository, $scopeRepository);
$refreshTokenService = new TokenService($objectManager, $refreshTokenRepository, $scopeRepository);

$authorizationGrant  = new AuthorizationGrant($authTokenService, $accessTokenService, $refreshTokenService);
$authorizationServer = new AuthorizationServer([$authorizationGrant]);

// Response contains the various parameters you can return
$response = $authorizationServer->handleRequest($request);
```

The request must be a valid `Psr\Http\Message\ServerRequestInterface`, and the authorization server returns a `Psr\Http\Message\ResponseInterface` object that is compliant with the OAuth2 specification.

#### Passing a user

[](#passing-a-user)

Most of the time, you want to associate an access token to a user. This is the only way to map a token to a user of your system. To do this, you can pass an optional second parameter to the `handleRequest`. This class must implements the `ZfrOAuth2\Server\Model\TokenOwnerInterface` interface:

```
$user = new User(); // must implement TokenOwnerInterface

// ...

$response = $authorizationServer->handleRequest($request, $user);
```

The AuthorizationServerMiddleware is able to do this for you and retrieve a user instance from a (configurable) request attribute. It is up to you to provide middleware which runs with a higher priority to add a TokenOwnerInterface instance to the request attribute.

Example of such a implementation which uses LaminasAuthentication and a TemplateRenderer from Mezzio.

```
final class OAuth2AuthorizationFlow
{
    /**
     * @var AuthenticationService
     */
    private $authenticationService;

    /**
     * @var ClientService
     */
    private $clientService;

    /**
     * @var TemplateRendererInterface
     */
    private $template;

    public function __construct(
        AuthenticationService $authenticationService,
        ClientService $clientService,
        TemplateRendererInterface $template
    ) {
        $this->authenticationService = $authenticationService;
        $this->clientService         = $clientService;
        $this->template              = $template;
    }

    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $out = null)
    {
        if ($this->authenticationService->hasIdentity()) {
            $request = $request->withAttribute('owner', $this->authenticationService->getIdentity());
        }

        if ($request->getMethod() === 'POST') {
            $post     = $request->getParsedBody();
            $approved = filter_var($post['approved'], FILTER_VALIDATE_BOOLEAN);

            if ($approved) {
                return $out($request, $response);
            }
        }

        $data  = [];
        $query = $request->getUri()->getQuery();
        parse_str($query, $data['query']);

        $data['client'] = $this->clientService->getClient($data['query']['client_id']);

        return new HtmlResponse($this->template->render('app::oauth2/authorize-request', $data));
    }
}

```

#### Revoking a token

[](#revoking-a-token)

ZfrOAuth2Server supports revoking access and refresh tokens using the [RFC 7009 specification](https://tools.ietf.org/html/rfc7009). You can use the `handleRevocationRequest` method in the AuthorizationServer. You must pass the following two POST parameters:

- `token`: the token to remove (either access or refresh token)
- `token_hint_type`: must be either `access_token` or `refresh_token` to indicate the authorization server which token type to revoke.

If you need to revoke a token that was issued for a non-public client (this means a client that has a secret key), then you MUST authenticate the request using the client id and secret.

> If you try to revoke a token that does not exist, it will return 200 SUCCESS request, according to the spec. However, if the token is valid, but cannot be deleted for any reason (database is down...), then it returns a 503 SERVICE UNAVAILABLE error!

### Using the resource server

[](#using-the-resource-server)

You can use the resource server to retrieve the access token (by automatically extracting the data from the HTTP headers). You can also specify scope constraints when retrieving the token:

```
$accessTokenService = new TokenService($objectManager, $accessTokenRepository, $scopeRepository);
$resourceServer     = new ResourceServer($accessTokenService);

if (!$token = $resourceServer->getAccessToken($request, ['write']) {
    // there is either no access token, or the access token is expired, or the access token does not have
    // the `write` scope
}
```

The ResourceServerMiddleware is able to do this for you, simply have it run before any other middleware.

Example mezzio expressive route configuration.

```
[
            'name'            => 'command::commerce::create-store',
            'path'            => '/commerce/create-store',
            'middleware'      => [
                ResourceServerMiddleware::class,
                MyActionMiddleware::class,
            ],
            'allowed_methods' => ['OPTIONS', 'POST'],
        ],

```

### Persistence layer

[](#persistence-layer)

As of version 0.8-beta1 ZfrOAuth2Server has been rewritten to be persistence layer agnostic. Meaning it can by used with any prefered persistence layer.

Currently these packages provide a persistence layer;

- [ZfrOAuth2ServerDoctrine](https://github.com/zf-fr/zfr-oauth2-server-doctrine) for Doctrine 2

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance17

Infrequent updates — may be unmaintained

Popularity39

Limited adoption so far

Community26

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 60.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~219 days

Recently: every ~499 days

Total

15

Last Release

1358d ago

PHP version history (5 changes)0.1.0PHP &gt;=5.4

0.7.0PHP &gt;=5.5

0.8.0-beta1PHP ^7.0

v0.9.0PHP ^7.2

0.10.0PHP ^7.4 || ^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/394428?v=4)[Sascha-Oliver Prolić](/maintainers/prolic)[@prolic](https://github.com/prolic)

![](https://www.gravatar.com/avatar/9e3c74232d02a5fedbcef4650bac1d1103be292d4a013f6f9e692befcc9bb7ca?d=identicon)[bakura10](/maintainers/bakura10)

![](https://www.gravatar.com/avatar/e42bb1eb4035d280d16210974fa60d0dbddeba8a061abec926e5e081d097231d?d=identicon)[bushbaby](/maintainers/bushbaby)

---

Top Contributors

[![basz](https://avatars.githubusercontent.com/u/143068?v=4)](https://github.com/basz "basz (273 commits)")[![bakura10](https://avatars.githubusercontent.com/u/1198915?v=4)](https://github.com/bakura10 "bakura10 (152 commits)")[![prolic](https://avatars.githubusercontent.com/u/394428?v=4)](https://github.com/prolic "prolic (18 commits)")[![awartoft](https://avatars.githubusercontent.com/u/1127626?v=4)](https://github.com/awartoft "awartoft (3 commits)")[![Ocramius](https://avatars.githubusercontent.com/u/154256?v=4)](https://github.com/Ocramius "Ocramius (3 commits)")[![ojhaujjwal](https://avatars.githubusercontent.com/u/4995501?v=4)](https://github.com/ojhaujjwal "ojhaujjwal (1 commits)")

---

Tags

serveroauthoauth 2

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/zfr-zfr-oauth2-server/health.svg)

```
[![Health](https://phpackages.com/badges/zfr-zfr-oauth2-server/health.svg)](https://phpackages.com/packages/zfr-zfr-oauth2-server)
```

###  Alternatives

[league/oauth2-server

A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.

6.6k136.0M248](/packages/league-oauth2-server)[friendsofsymfony/oauth-server-bundle

Symfony2 OAuth Server Bundle

1.1k15.1M133](/packages/friendsofsymfony-oauth-server-bundle)[chervand/yii2-oauth2-server

OAuth 2.0 server for Yii 2.0 with MAC tokens support.

1524.2k1](/packages/chervand-yii2-oauth2-server)[zfr/zfr-oauth2-server-module

Zend Framework 2 module for ZfrOAuth2Server

1236.2k1](/packages/zfr-zfr-oauth2-server-module)[klapaudius/oauth-server-bundle

Symfony(5.x to 8.x) OAuth Server Bundle

15547.3k2](/packages/klapaudius-oauth-server-bundle)[league/openid-connect-claims

An OpenID Connect ID claims set implementation

15242.9k2](/packages/league-openid-connect-claims)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
