定制 deadmantfa/yii2-oauth2-server 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

deadmantfa/yii2-oauth2-server

Composer 安装命令:

composer require deadmantfa/yii2-oauth2-server

包简介

OAuth 2.0 server for Yii 2.0 with MAC tokens support.

README 文档

README

This is a fork of the original chervand/yii2-oauth2-server plugin, updated for PHP 8+, league/oauth2-server ^9.1, and additional custom grants (including optional support for MAC tokens, token revocation, and more).

It provides:

  • A standards-compliant OAuth2.0 Server for Yii2
  • Refresh token support (RFC6749 / RFC7009)
  • MAC token support (experimental, draft-ietf-oauth-v2-http-mac-05)
  • Token revocation endpoints
  • Flexible DB-based migrations for storing OAuth2 clients, tokens, scopes, etc.
  • Easy integration with your Yii2 user component so you can unify login states and roles.

1. Installation

Add this package to your project:

composer require deadmantfa/yii2-oauth2-server

1.1 Apply DB Migrations

Run:

./yii migrate --migrationPath="@vendor/deadmantfa/yii2-oauth2-server/migrations"

This creates the default OAuth2-related tables (clients, tokens, scopes, etc.).

1.2 Generate Public & Private Keys

Follow League’s official instructions for generating private/public keys. Typically:

openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout -out public.key

Store them somewhere safe (e.g. @app/oauth2/private.key, @app/oauth2/public.key).

2. Basic Configuration

Below is a simple example of how to configure the module in your config/main.php (or similar file).

return [
    // ...
    'bootstrap' => [
        'oauth2', // ensures module is bootstrapped
        // ...
    ],
    'modules' => [
        'oauth2' => [
            'class' => \deadmantfa\yii2\oauth2\server\Module::class,
            
            // Your key file paths:
            'privateKey' => __DIR__ . '/../oauth2/private.key',
            'publicKey'  => __DIR__ . '/../oauth2/public.key',

            // Encryption key used for JWT, typically 32+ bytes
            'encryptionKey' => 'some-random-binary-string',
            
            // Example: define any custom Repositories or model classes
            'components' => [
                'accessTokenRepository' => [
                    'class' => \deadmantfa\yii2\oauth2\server\components\Repositories\AccessTokenRepository::class,
                ],
                'refreshTokenRepository' => [
                    'class' => \deadmantfa\yii2\oauth2\server\components\Repositories\RefreshTokenRepository::class,
                ],
                'clientRepository' => [
                    'class' => \deadmantfa\yii2\oauth2\server\components\Repositories\ClientRepository::class,
                ],
                'scopeRepository' => [
                    'class' => \deadmantfa\yii2\oauth2\server\components\Repositories\ScopeRepository::class,
                ],
                // ...
            ],

            // Optional caching logic for repositories
            'cache' => [
                \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface::class => [
                    'cacheDuration' => 3600,
                    'cacheDependency' => new \yii\caching\FileDependency(['fileName' => 'AccessTokenRepoCache.txt']),
                ],
                // ...
            ],

            // Register the grant types you want
            'enableGrantTypes' => static function (\deadmantfa\yii2\oauth2\server\Module $module) {
                $server = $module->authorizationServer;
                
                // Password + Refresh Token Grant
                $passwordGrant = new \League\OAuth2\Server\Grant\PasswordGrant(
                    $module->getComponent('userRepository'),
                    $module->getComponent('refreshTokenRepository')
                );
                $passwordGrant->setRefreshTokenTTL(new \DateInterval('P1M'));
                $server->enableGrantType($passwordGrant, new \DateInterval('PT1H'));

                // Client Credentials
                $server->enableGrantType(new \League\OAuth2\Server\Grant\ClientCredentialsGrant());
                
                // Refresh Token
                $refreshGrant = new \League\OAuth2\Server\Grant\RefreshTokenGrant(
                    $module->getComponent('refreshTokenRepository')
                );
                $refreshGrant->setRefreshTokenTTL(new \DateInterval('P1M'));
                $server->enableGrantType($refreshGrant, new \DateInterval('PT1H'));

                // (Optional) Revoke Grant
                $server->enableGrantType(new \deadmantfa\yii2\oauth2\server\components\Grant\RevokeGrant(
                    $module->getComponent('refreshTokenRepository'),
                    $module->publicKey
                ));
            },
        ],
    ],
    // ...
];

That’s enough to spin up the Authorization Server portion. You’ll have endpoints like:

  • POST /oauth2/token (to exchange credentials for tokens)
  • POST /oauth2/revoke (to revoke a token, if you enabled RevokeGrant)

3. Integrating with Your user Component

3.1 Provide a UserRepositoryInterface

In League OAuth2, you need a repository that implements UserRepositoryInterface. Typically, you can have your user model implement UserEntityInterface and provide a getUserEntityByUserCredentials() method:

class MyUserRepository implements UserRepositoryInterface
{
    public function getUserEntityByUserCredentials($username, $password, $grantType, ClientEntityInterface $clientEntity)
    {
        $user = User::findOne(['username' => $username]);
        if (!$user || !Yii::$app->security->validatePassword($password, $user->password_hash)) {
            return null;
        }
        return $user; // which implements UserEntityInterface
    }
}

3.2 Linking to Your Identity in Yii2

If you want to unify your “OAuth2 user ID” with your standard Yii user identity:

  1. In config/main.php, set 'identityClass' => MyUser::class in your user component.
  2. Ensure your model has getId() returning the correct user identifier.
  3. Make sure the above repository uses that same model.

4. Resource Server (Protecting Your API)

To validate tokens in your controllers, attach an authenticator that checks the Authorization: Bearer <token> header. For example:

class MyApiController extends \yii\rest\ActiveController
{
    public function behaviors()
    {
        $behaviors = parent::behaviors();

        unset($behaviors['authenticator']);
        unset($behaviors['rateLimiter']);

        /** @var \deadmantfa\yii2\oauth2\server\Module $auth */
        $auth = Yii::$app->getModule('oauth2');

        $behaviors['authenticator'] = [
            'class' => \yii\filters\auth\CompositeAuth::class,
            'authMethods' => [
                [
                    'class' => \deadmantfa\yii2\oauth2\server\components\AuthMethods\HttpBearerAuth::class,
                    'publicKey' => $auth->publicKey,
                    'cache'     => $auth->cache,
                ],
                // or add Mac tokens:
                // [
                //   'class' => \deadmantfa\yii2\oauth2\server\components\AuthMethods\HttpMacAuth::class,
                // ],
            ],
        ];

        $behaviors['rateLimiter'] = [
            'class' => \yii\filters\RateLimiter::class,
        ];

        return $behaviors;
    }
}

Any requests with an invalid or no token get a 401 response.

5. MAC Tokens (Optional)

If you want MAC tokens (still a draft), you can enable them by adding:

use \deadmantfa\yii2\oauth2\server\components\AuthMethods\HttpMacAuth;

$behaviors['authenticator'] = [
    'class' => \yii\filters\auth\CompositeAuth::class,
    'authMethods' => [
        [
            'class' => HttpMacAuth::class,
            'publicKey' => $auth->publicKey,
            'cache' => $auth->cache,
        ],
    ],
];

And in your module’s enableGrantTypes, you can enable a MacTokenResponse instead of BearerTokenResponse.

6. Revoke Tokens (RFC7009)

Add the RevokeGrant in enableGrantTypes:

$server->enableGrantType(
    new \deadmantfa\yii2\oauth2\server\components\Grant\RevokeGrant(
        $module->refreshTokenRepository,
        $module->publicKey
    )
);

Then request:

POST /oauth2/revoke
Authorization: Basic <client_id:client_secret base64>
Content-Type: application/json

{
  "token": "<refresh_token or access_token>"
}

The plugin revokes tokens in the DB. The next time the resource server checks that token, it’s marked invalid.

7. Optional CORS Support

If you want to handle CORS within this plugin (e.g. for /oauth2/token calls in front-end apps), you can either:

  • (A) Configure CORS globally in your Yii2 app (recommended for most setups), or
  • (B) Enable a built-in CORS filter inside this module’s controllers.

7.1 Sample Global CORS

In your main config/main.php:

'on beforeRequest' => function ($event) {
    Yii::$app->attachBehavior('globalCors', [
        'class' => \yii\filters\Cors::class,
        'cors' => [
            'Origin' => ['https://yourfrontend.com'],
            'Access-Control-Allow-Credentials' => true,
            'Access-Control-Allow-Headers' => ['Authorization', 'Content-Type', 'X-Requested-With', 'Accept', 'Origin', 'Cache-Control', 'Pragma'],
            'Access-Control-Allow-Methods' => ['GET','POST','OPTIONS','PUT','DELETE'],
            'Access-Control-Max-Age' => 3600,
        ],
    ]);
},

7.2 Built-in CORS in Module

If you want the plugin to handle it internally, you can define a property like:

'modules' => [
    'oauth2' => [
        'class' => \deadmantfa\yii2\oauth2\server\Module::class,
        'enableCors' => true,
        'corsConfig' => [
            'class' => \yii\filters\Cors::class,
            'cors' => [
                'Origin' => ['*'],
                'Access-Control-Allow-Credentials' => true,
                'Access-Control-Allow-Methods' => ['POST','OPTIONS'],
                'Access-Control-Allow-Headers' => ['Authorization','Content-Type','X-Requested-With','Accept','Origin','Cache-Control','Pragma'],
                'Access-Control-Max-Age' => 3600,
            ],
        ],
        // ...
    ],
],

8. Additional Notes

  • For custom grants (like a FirebaseGrant or a PasswordlessGrant), implement GrantTypeInterface or extend AbstractGrant and register it in enableGrantTypes.
  • You can store user IDs as UUID strings or integers. Just ensure your UserEntityInterface::getIdentifier() returns a string that the library can embed in the token.
  • The library handles JWT signing/verification, so you just need to provide your private/public RSA keys.

deadmantfa/yii2-oauth2-server 适用场景与选型建议

deadmantfa/yii2-oauth2-server 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 477 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 01 月 03 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「authorization」 「api」 「Authentication」 「oauth」 「oauth2」 「server」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 deadmantfa/yii2-oauth2-server 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 deadmantfa/yii2-oauth2-server 我们能提供哪些服务?
定制开发 / 二次开发

基于 deadmantfa/yii2-oauth2-server 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 477
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 21
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 15
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-01-03