Laravel Passport 令牌生命周期

Posted

技术标签:

【中文标题】Laravel Passport 令牌生命周期【英文标题】:Laravel Passport token lifetime 【发布时间】:2017-07-25 08:48:51 【问题描述】:

我不明白我做错了什么。 我无法设置令牌过期时间。

<?php

namespace App\Providers;

class AuthServiceProvider extends ServiceProvider

    public function boot()
    
        $this->registerPolicies();

        Passport::tokensExpireIn(Carbon::now()->addDays(1));
        Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
    

但是当我打电话给$user-&gt;createToken() 时,例如这样:

<?php
// as a demo
namespace App\Http\Middleware;

class ParseSpecialToken

    public function handle($request, Closure $next)
    
        $user = User::find(1);
        $accessToken = $user->createToken('Some token')->accessToken;
        $request->headers->add(['Authorization' => 'Bearer '. $accessToken]);

        return $next($request);
    

代币有效期仍然是 1 年,而不是 1 天。为什么?如何更改exp时间?

【问题讨论】:

【参考方案1】:

以下是用于更新所有授权类型的到期时间的方法:

个人访问令牌:

public function boot()
        $this->registerPolicies();

        Passport::routes();
        Passport::personalAccessTokensExpireIn(Carbon::now()->addHours(24));
        Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));

休息

public function boot()
        $this->registerPolicies();

        Passport::routes();
        Passport::tokensExpireIn(Carbon::now()->addHours(24));
        Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));

只需在 AuthServiceProvider 的 boot 方法中更新上述代码即可。

【讨论】:

【参考方案2】:

createToken() 方法创建个人访问令牌。默认情况下,这些令牌在 1 年后过期(或 100 年,如果由 laravel/passport Passport::tokensExpireIn() 或Passport::refreshTokensExpireIn() 方法修改。

laravel/护照 >= 7.0.4

Passport 版本 7.0.4 添加了一个新方法 Passport::personalAccessTokensExpireIn(),允许您更新个人访问令牌的到期时间。如果您使用的是此版本或更高版本,则可以将此方法调用添加到您的 AuthServiceProvider::boot() 方法中。

Passport::personalAccessTokensExpireIn(Carbon::now()->addDays(1));

laravel/护照

如果你还不是7.0.4版本的护照,你仍然可以修改个人访问令牌的过期时间,但更手动。您将需要启用具有所需到期时间的个人访问授权的新实例。这也可以在您的 AuthServiceProvider::boot() 方法中完成。

$server = $this->app->make(\League\OAuth2\Server\AuthorizationServer::class);
$server->enableGrantType(new \Laravel\Passport\Bridge\PersonalAccessGrant(), new \DateInterval('P100Y'));

注意

修改数据库中的expires_at 字段不会做任何事情。真正的到期日期存储在令牌本身内。此外,尝试修改 JWT 令牌中的 exp 声明将不起作用,因为令牌已签名并且对它的任何修改都会使其无效。因此,您现有的所有令牌都将具有其原始到期时间,并且无法更改。如果需要,您将需要重新生成新令牌。

【讨论】:

谢谢。我可以说这是有效的答案。我已经使用JWT.io 检查了令牌的生命周期。只需输入令牌,然后查看“exp”变量。适用于 Laravel 5.5; lcobucci/jwt 3.3.3; laravel/passport ~4.0 只需添加一些额外的提示。在设置令牌生命周期之前,您应该检查文件 oauth 公钥和私钥。这将在需要生成新的护照密钥时为您提供帮助。这是我的 sn-p 代码,gist.github.com/fendis0709/e86f25bfa4006e20ca6a96eed8df9b4e【参考方案3】:

Passport 文档似乎回答了这个问题

https://laravel.com/docs/5.6/passport#token-lifetimes

AuthServiceProviderboot方法中调用Passport::tokenExpiresIn()

public function boot()

    $this->registerPolicies();

    Passport::routes();

    Passport::tokensExpireIn(now()->addDays(15));

    Passport::refreshTokensExpireIn(now()->addDays(30));

【讨论】:

【参考方案4】:

啊,发现个人令牌总是长期存在的,无法配置:(

【讨论】:

【参考方案5】:

请参阅 this implementation 和 here 如何将 PassportServiceProvider 替换为您的。它适用于 Laravel 5.5

【讨论】:

【参考方案6】:

我能够通过在我的项目中创建一个 PassportServiceProvider 来延长个人访问令牌的生命周期,该 PassportServiceProvider 从 laravel-passport 包中扩展 PassportServiceProvider。然后我只是添加了这个方法来覆盖 PassportServiceProvider 中的那个。



    /**
     * Register the authorization server.
     *
     * @return void
     */
    protected function registerAuthorizationServer()
    
        $this->app->singleton(AuthorizationServer::class, function () 
            return tap($this->makeAuthorizationServer(), function ($server) 
                $server->enableGrantType(
                    $this->makeAuthCodeGrant(), Passport::tokensExpireIn()
                );

                $server->enableGrantType(
                    $this->makeRefreshTokenGrant(), Passport::tokensExpireIn()
                );

                $server->enableGrantType(
                    $this->makePasswordGrant(), Passport::tokensExpireIn()
                );

                $server->enableGrantType(
                    new PersonalAccessGrant(), Passport::tokensExpireIn() // this is the line that was updated from the original method
                );

                $server->enableGrantType(
                    new ClientCredentialsGrant(), Passport::tokensExpireIn()
                );

                if (Passport::$implicitGrantEnabled) 
                    $server->enableGrantType(
                        $this->makeImplicitGrant(), Passport::tokensExpireIn()
                    );
                
            );
        );
    

然后我刚刚更新了 app.php 配置文件中的提供程序以使用我项目中的提供程序。

【讨论】:

【参考方案7】:

你可以这样做:

$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
$token->expires_at =
        Carbon::now()->addDays(env('PERSONAL_ACCESS_TOKEN_EXPIRY__DAYS'));

$token->save();

【讨论】:

DB表中expires_at的值仅供参考。过期时间戳被编码到 JWT 令牌中。这行不通。 我认为答案是基于帖子https://medium.com/modulr/create-api-authentication-with-passport-of-laravel-5-6-1dc2d400a7f 但它不起作用【参考方案8】:

文件:AuthServiceProvider.php

添加这些行

use Laravel\Passport\Bridge\PersonalAccessGrant;
use League\OAuth2\Server\AuthorizationServer;

在启动函数中添加如下代码

public function boot() 
     Passport::routes();
     $lifetime = new \DateInterval('PT24H'); // For 24hours

     $this->app->get(AuthorizationServer::class)->enableGrantType(new PersonalAccessGrant(), $lifetime);

【讨论】:

解释为什么这会解决问题以及用户哪里出错了 或者它如何添加比问题的现有答案更多的信息。仅供参考,我在一个多月前的回答已经涵盖了这一点。【参考方案9】:

是的,我只是浪费了一天时间才发现 VERSION = '5.8' 中的这个问题。

现在,也许我们需要修改 你的项目/供应商/laravel/passport/src/Passport.php。

改变这个 -----> new DateInterval('P1Y') 。它是php函数,表示一个日期间隔。

D---> 表示日 Y---> 表示年份 M---> 表示月份

护照中的三种令牌

1.tokensExpireIn 在 303 行。

    personalAccessTokensExpireIn 在 341 行。

    refreshTokensExpireIn 在 322 行。

【讨论】:

修改供应商代码不是一个好主意。它将被您的下一次作曲家更新覆盖,并且供应商更改不会记录在您的存储库中,因此它们无法部署到新环境。我的回答向您展示了如何在不修改您的供应商代码的情况下解决个人访问令牌的问题。

以上是关于Laravel Passport 令牌生命周期的主要内容,如果未能解决你的问题,请参考以下文章

Laravel cookie 会话生命周期

如何在 Keycloak 中指定刷新令牌的生命周期

具有自定义生命周期的身份服务器 4 访问令牌

Laravel的生命周期

laravel生命周期

Laravel 请求的生命周期介绍