PHPackages                             ridibooks/oauth2 - 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. ridibooks/oauth2

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

ridibooks/oauth2
================

Ridibooks OAuth2

v0.3.1(6y ago)328.6k1[2 issues](https://github.com/ridi/php-oauth2/issues)MITPHPCI failing

Since Mar 20Pushed 6y ago6 watchersCompare

[ Source](https://github.com/ridi/php-oauth2)[ Packagist](https://packagist.org/packages/ridibooks/oauth2)[ RSS](/packages/ridibooks-oauth2/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (10)Dependencies (8)Versions (15)Used By (0)

ridibooks/oauth2
================

[](#ridibooksoauth2)

[![Build Status](https://camo.githubusercontent.com/9c940dfa59fd0bf3bf9252c1c7ed9ebf83f4c51e4e2de80a2d55c87eb1abf38b/68747470733a2f2f7472617669732d63692e6f72672f726964692f7068702d6f61757468322e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/ridi/php-oauth2)

소개
--

[](#소개)

- OAuth2 클라이언트와 리소스 서버를 구축하기 위한 PHP 라이브러리입니다.
- Ridi 스타일 가이드([내부 서비스간의 SSO](https://github.com/ridi/style-guide/blob/master/API.md#%EB%82%B4%EB%B6%80-%EC%84%9C%EB%B9%84%EC%8A%A4%EA%B0%84%EC%9D%98-sso))에 따라 작성 되었습니다.
- JWK Caching 를 선택적으로 지원합니다. [psr-6](https://www.php-fig.org/psr/psr-6/)의 구현체를 JwtTokenValidator에 주입하면 캐싱 기능을 사용할 수 있습니다.

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

[](#requirements)

- `PHP 7.2` or higher
- `php7.2-gmp` web-token decryption 모듈을 위해서는 php7.2-gmp 를 os 내에 설치해줘야 합니다. 따라서 이 라이브러리 클라이언트들의 OS 혹은 도커 이미지 내에 꼭 설치해주시길 바랍니다. [참고 PR](https://github.com/ridibooks-docker/viewer-php/pull/1)
- `silex/silex v1.3.x` (optional)
- `symfony/symfony v4.x.x` (optional)
- `guzzlehttp/guzzle` (optional)

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

[](#installation)

```
composer require ridibooks/oauth2
```

Usage
-----

[](#usage)

### `JwtTokenValidator Without Caching`

[](#jwttokenvalidator-without-caching)

```
use Ridibooks\OAuth2\Authorization\Validator\JwtTokenValidator;

$access_token = '...';

try {
    $jwk_url = $this->configs['jwk_url'];
    $validator = new JwtTokenValidator($jwk_url);
    $validator->validateToken($access_token);
} catch (AuthorizationException $e) {
	// handle exception
}
```

### `JwtTokenValidator With Caching`

[](#jwttokenvalidator-with-caching)

```
use Ridibooks\OAuth2\Authorization\Validator\JwtTokenValidator;

$access_token = '...';

try {
    $jwk_url = $this->configs['jwk_url'];
    $cache_item_pool = new FilesystemAdapter(); // [psr-6](https://www.php-fig.org/psr/psr-6/) Implementation Adaptor
    $validator = new JwtTokenValidator($jwk_url, $cache_item_pool);
    $validator->validateToken($access_token);
} catch (AuthorizationException $e) {
	// handle exception
}
```

### `ScopeChecker`

[](#scopechecker)

```
$required = ['write', 'read'];
if (ScopeChecker::every($required, $granted)) {
	// pass
}
```

### `Granter`

[](#granter)

```
$client_info = new ClientInfo('client_id', 'client_secret', ['scope'], 'redirect_uri');
$auth_server_info = new AuthorizationServerInfo('authorization_url', 'token_url');

$granter = new Granter($client_info, $auth_server_info);
$authorization_url = $granter->authorize();
// Redirect to `$authorization_url`
```

Usage: with Silex Provider
--------------------------

[](#usage-with-silex-provider)

`OAuth2ServiceProvider`를 Silex 애플리케이션에 등록(`register`)해 사용한다.

### Services

[](#services)

- **`OAuth2ProviderKeyConstant::GRANTER`**
    - `authorize(string $state, string $redirect_uri = null, array $scope = null): string`: `/authorize`를 위한 URL을 반환
- **`OAuth2ProviderKeyConstant::AUTHORIZER`**
    - `autorize(Request $request): JwtToken`: `access_token` 유효성 검사 후 `JwtToken` 객체를 반환
- **`OAuth2ProviderKeyConstant::MIDDLEWARE`**
    - `authorize(OAuth2ExceptionHandlerInterface $exception_handler = null, UserProviderInterface $user_provider = null, array $required_scopes = [])`: 미들웨어를 반환

#### Example: `OAuth2ProviderKeyConstant::MIDDLEWARE` Service

[](#example-oauth2providerkeyconstantmiddleware-service)

```
use Ridibooks\OAuth2\Silex\Constant\OAuth2ProviderKeyConstant as KeyConstant;
use Ridibooks\OAuth2\Silex\Handler\LoginRequiredExceptionHandler;
use Ridibooks\OAuth2\Silex\Provider\OAuth2ServiceProvider;
use Ridibooks\OAuth2\Authorization\Validator\JwtTokenValidator;
use Example\UserProvder;

// `OAuth2ServiceProvider` 등록
$app->register(new OAuth2ServiceProvider(), [
	KeyConstant::CLIENT_ID => 'example-client-id',
	KeyConstant::CLIENT_SECRET => 'example-client-secret',
	KeyConstant::JWT_VALIDATOR => new JwtTokenValidator($jwk_url)
]);

// 미들웨어 등록
$app->get('/auth-required', [$this, 'authRequiredApi'])
	->before($app[KeyConstant::MIDDLEWARE]->authorize(new LoginRequiredExceptionHandler(), new UserProvider());

public function authRequiredApi(Application $app)
{
	// 사용자 추출
	$user = $app[KeyConstant::USER];
	...
}
```

#### Example: `OAuth2ProviderKeyConstant::AUTHORIZER` Service

[](#example-oauth2providerkeyconstantauthorizer-service)

```
use Ridibooks\OAuth2\Authorization\Authorizer;
use Ridibooks\OAuth2\Authorization\Exception\AuthorizationException;
use Ridibooks\OAuth2\Silex\Constant\OAuth2ProviderKeyConstant;
use Ridibooks\OAuth2\Silex\Provider\OAuth2ServiceProvider;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Ridibooks\OAuth2\Authorization\Validator\JwtTokenValidator;

...

// `OAuth2ServiceProvider` 등록
$app->register(new OAuth2ServiceProvider(), [
	KeyConstant::CLIENT_ID => 'example-client-id',
	KeyConstant::CLIENT_SECRET => 'example-client-secret',
    KeyConstant::JWT_VALIDATOR => new JwtTokenValidator($jwk_url)
]);

...

$app->get('/', function (Application $app, Request $request) {
	/** @var Authorizer $authorizer */
	$authorizer = $app[OAuth2ProviderKeyConstant::AUTHORIZER];
	try {
		$token = $authorizer->authorize($request);
		return $token->getSubject();
	} catch (AuthorizationException $e) {
		// handle authorization error ...
	}
});
```

Usage: with Symfony Bundle
--------------------------

[](#usage-with-symfony-bundle)

### Services

[](#services-1)

- **`Granter()`**
    - `OAuth2ServiceProvider::getGranter()`
    - `Granter::authorize(string $state, string $redirect_uri = null, array $scope = null): string`: `/authorize`를 위한 URL을 반환
- **`Authorizer()`**
    - `OAuth2ServiceProvider::getAuthorizer()`
    - `Authorizer::autorize(Request $request): JwtToken`: `access_token` 유효성 검사 후 `JwtToken` 객체를 반환
- **`OAuth2Middleware`**
    - `OAuth2ServiceProvider::getMiddleware()`
    - `OAuth2ServiceProvider` 생성 시, Symfony Event Subscriber로 등록

### Example: `OAuth2Middleware` Service

[](#example-oauth2middleware-service)

#### Configuration

[](#configuration)

- 설정 예시는 `tests/Symfony`에서 살펴볼 수 있습니다.

##### 1. `OAuth2ServiceProviderBundle` 등록

[](#1-oauth2serviceproviderbundle-등록)

```
# example: /config/bundles.php

return [
    ...,
    Ridibooks\OAuth2\Symfony\OAuth2ServiceProviderBundle::class => ['all' => true]
];
```

##### 2. Parameter 및 Service 설정

[](#2-parameter-및-service-설정)

- '%env(VARIABLE)%'을 이용해 environment variable을 이용할 수 있습니다.
- Required
    - client\_id
    - client\_secret
    - authorize\_url
    - token\_url
    - jwk\_url
    - user\_info\_url
    - token\_cookie\_domain
    - default\_exception\_handler
- optional
    - client\_default\_scope
    - client\_default\_redirect\_uri
    - default\_user\_provider
    - cache\_item\_pool # [psr-6](https://www.php-fig.org/psr/psr-6/)의 구현체를 주입하면 Jwk 요청 시 캐싱 기능을 사용할 수 있습니다.

```
# example: /config/packages/o_auth2_service_provider.yml

o_auth2_service_provider:
  client_id: '%env(CLIENT_ID)%'
  client_secret: '%env(CLIENT_SECRET)%'
  authorize_url: https://account.dev.ridi.io/ridi/authorize/
  token_url: https://account.dev.ridi.io/oauth2/token/
  jwk_url: https://account.dev.ridi.io/oauth2/keys/public
  user_info_url: https://account.dev.ridi.io/accounts/me/
  token_cookie_domain: .ridi.io

  default_exception_handler: Ridibooks\OAuth2\Example\DefaultExceptionHandler
  cache_item_pool: Symfony\Component\Cache\Adapter\FilesystemAdapter
```

```
# example: /config/services.yml

services:
  Ridibooks\OAuth2\Example\ExampleController:
    class: Ridibooks\OAuth2\Example\ExampleController
    autowire: true
    autoconfigure: true
    public: false
    arguments:
      - '@oauth2_service_provider'
```

##### 3. Controller 설정

[](#3-controller-설정)

```
namespace Ridibooks\OAuth2\Example;

use Ridibooks\OAuth2\Symfony\Annotation\OAuth2;
use Ridibooks\OAuth2\Symfony\Provider\OAuth2ServiceProvider;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class ExampleController extends Controller
{
    /** @var OAuth2ServiceProvider */
    private $oauth2_service_provider;

    /**
     * @param OAuth2ServiceProvider $oauth2_service_provider
     */
    public function __construct(OAuth2ServiceProvider $oauth2_service_provider)
    {
        $this->oauth2_service_provider = $oauth2_service_provider;
    }

    /**
     * @Route("/oauth2", methods={"GET"})
     * @OAuth2()
     *
     * @param Request $request
     * @return Response
     */
    public function normal(Request $request): Response
    {
        $user = $this->oauth2_service_provider->getMiddleware()->getUser();

        return new JsonResponse([
            'u_idx' => $user->getUidx(),
            'u_id' => $user->getUid()
        ]);
    }
}
```

#### OAuth2 Exception Handler 설정

[](#oauth2-exception-handler-설정)

- Exception Handler는 OAuth2 과정 중, 오류 발생 시 Exception 상황을 처리하는 역할을 담당합니다.
- Application Controller에서 `default_exception_handler` 파라미터로 지정한 Exception Handler가 아닌 별도의 Exception Handler를 이용하려는 경우, 아래 절차를 따릅니다.
    - `Ridibooks\OAuth2\Symfony\Handler\OAuth2ExceptionHandlerInterface`를 implement한 Exception Handler를 생성합니다.
        - example: `Ridibooks\Test\OAuth2\Symfony\TestExceptionHandler`
    - Application Controller의 `@OAuth2` Annotation에서 `exception_handler` 속성을 지정합니다.
        - example: `@OAuth2(exception_handler="Ridibooks\Test\OAuth2\Symfony\TestExceptionHandler")`

#### Custom User Provider 설정

[](#custom-user-provider-설정)

- User Provider는 인증 이후, User 정보를 가져오는 역할을 담당합니다.
- `default_user_provider` 파라미터를 지정하지 않은 경우, 기본적으로 `Ridibooks\OAuth2\Symfony\Provider\DefaultUserProvider`를 이용합니다.
- Application Controller에서 `default_user_provider` 파라미터로 지정한 User Provider가 아닌 별도의 User Provider를 이용하려는 경우, 아래 절차를 따릅니다.
    - `Ridibooks\OAuth2\Symfony\Provider\UserProviderInterface`를 implement한 User Provider를 생성합니다.
    - Application Controller의 `@OAuth2` Annotation에서 `user_provider` 속성을 지정합니다.

```
namespace Ridibooks\OAuth2\Example;

use Ridibooks\OAuth2\Authorization\Token\JwtToken;
use Ridibooks\OAuth2\Symfony\Provider\OAuth2ServiceProvider;
use Ridibooks\OAuth2\Symfony\Provider\UserProviderInterface;
use Symfony\Component\HttpFoundation\Request;

class CustomUserProvider implement UserProviderInterface
{
    /**
     * @param JwtToken $token
     * @param Request $request
     * @param OAuth2ServiceProvider $oauth2_service_provider
     * @return User
     */
    public function getUser(JwtToken $token, Request $request, OAuth2ServiceProvider $oauth2_service_provider): User
    {
        ...
    }
}
```

```
namespace Ridibooks\OAuth2\Example;

use Ridibooks\OAuth2\Symfony\Annotation\OAuth2;
use Ridibooks\OAuth2\Symfony\Provider\OAuth2ServiceProvider;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class ExampleController extends Controller
{
    /**
     * @Route("/oauth2", methods={"GET"})
     * @OAuth2(user_provider="Ridibooks\OAuth2\Example\CustomUserProvider")
     *
     * @param Request $request
     * @return Response
     */
    public function normal(Request $request): Response
    {
        ...
    }
}
```

#### Cache Item Pool 설정

[](#cache-item-pool-설정)

- Cache Item Pool 은 Jwk 를 캐싱하는 역할을 담당합니다.

#### 유의할 점

[](#유의할-점)

- [Jwk Multi signatures](https://stackoverflow.com/questions/50031985/what-is-a-use-case-for-having-multiple-signatures-in-a-jws-that-uses-jws-json-se) 를 지원하지 않습니다. 오직 첫 번째 인덱스의 시그니쳐를 가져와서 decode 합니다.
- Jwk Cache File 의 TTL(Time To Live)는 5분 입니다.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance7

Infrequent updates — may be unmaintained

Popularity28

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 54.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 ~50 days

Recently: every ~107 days

Total

14

Last Release

2325d ago

### Community

Maintainers

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

![](https://www.gravatar.com/avatar/8260c131d6a3a12a327d78328de6f99203187abacd4571ec2cfd4dfeb4a1b2cb?d=identicon)[ridi](/maintainers/ridi)

![](https://www.gravatar.com/avatar/97c6861c3957bcd1959cb4bef92398fb12c77690355e4a6659b8787cc0d95cc0?d=identicon)[antiline](/maintainers/antiline)

![](https://www.gravatar.com/avatar/48fc7d97c206e0a1ea0c219ccfe569881498662eafa57113ae18e87ee9be4c3a?d=identicon)[kyungmi](/maintainers/kyungmi)

---

Top Contributors

[![academey](https://avatars.githubusercontent.com/u/14977613?v=4)](https://github.com/academey "academey (35 commits)")[![kyungmi](https://avatars.githubusercontent.com/u/8926395?v=4)](https://github.com/kyungmi "kyungmi (23 commits)")[![namenu](https://avatars.githubusercontent.com/u/243097?v=4)](https://github.com/namenu "namenu (5 commits)")[![freekering](https://avatars.githubusercontent.com/u/2075765?v=4)](https://github.com/freekering "freekering (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[spomky-labs/lexik-jose-bridge

Bridge to allow the use of web-token/jwt-framework with the Lexik JWT Authentication Bundle

35444.0k](/packages/spomky-labs-lexik-jose-bridge)

PHPackages © 2026

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