【问题标题】:OAuth: Proper way to generate/reuse tokenOAuth:生成/重用令牌的正确方法
【发布时间】:2020-06-26 02:26:06
【问题描述】:

这是我在用户提供正确凭据时管理 OAuth 身份验证的方式:

    protected function authenticated(Request $request, User $user)
    {
        return response()->json([
            'token' => $user->createToken('my_app')->accessToken
        ]);
    }

我尝试使用使用 OAuth 的默认 Laravel 身份验证(护照)。我遇到的问题是每次用户连接时,它都会在oauth_access_token 表中创建一个新条目。

推荐的方法是什么?

让它像这样增长,在这个表中有nb_user * nb_authentications 条目?

或者我应该在用户进行身份验证时检查是否已经拥有一个有效的令牌以将其返回给他,或者在创建新令牌时删除其他令牌?

【问题讨论】:

    标签: php laravel oauth


    【解决方案1】:

    用户和客户端有责任保存他的访问令牌代码,客户端应用程序必须制定适当的机制并将密钥存储在安全的地方。

    此外,在生成密钥时必须使用安全连接,例如使用 https。 稍后,每当请求登录页面时为用户生成访问令牌将被视为安全漏洞,因为数据库将包含许多有效且可使用且难以跟踪的访问令牌。

    因此,处理此问题的首选方法是在创建新的密钥访问令牌后立即删除为用户创建的先前访问令牌。

    在 Laravel 7 [See the official documentation] 中推荐的方式是使用事件来跟踪生成并删除旧的:

    EventServiceProvider 类中,找到 $listen 数组并附加 Passport 侦听器:

    'Laravel\Passport\Events\AccessTokenCreated' => [
                'App\Listeners\RevokeOldTokens',
            ],
    

    然后我们执行如下 artisan 命令生成监听器:

    php artisan event:generate
    

    然后在App\Listeners\文件夹中找到监听器,在handle方法中输入以下代码:

    Token::where([
                ['user_id', $event->userId],
                ['id', '<>', $event->tokenId]
            ])->delete();
    

    通过编写上面的代码,我们告诉 Laravel 通过他的 userID 找到用户访问令牌,他创建了一个新的访问令牌,并且访问令牌 ID 与刚刚生成的新访问令牌 ID 不同。当此数据在数据库中时,意味着用户拥有旧的访问令牌,我们将其删除。

    监听类文件内容如下:

    <?php
    
    namespace App\Listeners;
    
    use Laravel\Passport\Events\AccessTokenCreated;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Queue\InteractsWithQueue;
    use Laravel\Passport\Token;
    
    class RevokeOldTokens
    {
        /**
         * Create the event listener.
         *
         * @return void
         */
        public function __construct()
        {
            //
        }
    
        /**
         * Handle the event.
         *
         * @param  AccessTokenCreated  $event
         * @return void
         */
        public function handle(AccessTokenCreated $event)
        {
            Token::where([
                ['user_id', $event->userId],
                ['id', '<>', $event->tokenId]
            ])->delete();
        }
    }
    

    现在尝试生成一个新的用户访问代码,您会注意到以前的访问令牌已从数据库中删除。

    【讨论】:

    • 感谢您的回答。我会在尝试时将其标记为正确答案!你有官方资源的链接吗?
    • @DavidAlvarez 不客气。是的,我用 Laravel 文档的链接更新了我的答案laravel.com/docs/7.x/passport#events
    猜你喜欢
    • 2011-07-24
    • 2021-09-28
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    • 2018-07-28
    • 2011-02-15
    相关资源
    最近更新 更多