繁体   English   中英

Laravel Sanctum 令牌到期基于上次使用

[英]Laravel Sanctum token expiration based on last usage

我已经在配置文件中设置了 sanctum 令牌过期时间,比如说 24 小时:

/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. If this value is null, personal access tokens do
| not expire. This won't tweak the lifetime of first-party sessions.
|
*/

'expiration' => 24 * 60,

这样做,我的令牌在这段时间之后变得无效。 相反,我想做的是根据令牌的 last_used_at 属性检查此过期时间。

为了更好地理解这里是一个简单的例子:

  • 用户在星期一 - 9:00 登录 -> 创建一个新的令牌,有效期为 24 小时
  • 仍然在星期一 - 13:00 他提出请求 -> 令牌的 last_used_at 值设置为这个时间
  • 现在第二天,在星期二 - 11:00,用户想要提出请求......验证失败,因为它已经超过了令牌创建的 24 小时。 但距离上次使用时间仍然是 24 小时 window。

在对源文件进行了一些挖掘之后,我找到了 Guard,它会进行这项检查。

供应商/laravel/sanctum/src/Guard.php

protected function isValidAccessToken($accessToken): bool
{
    if (! $accessToken) {
        return false;
    }

    $isValid =
        (! $this->expiration || $accessToken->created_at->gt(now()->subMinutes($this->expiration)))
        && $this->hasValidProvider($accessToken->tokenable);

    if (is_callable(Sanctum::$accessTokenAuthenticationCallback)) {
        $isValid = (bool) (Sanctum::$accessTokenAuthenticationCallback)($accessToken, $isValid);
    }

    return $isValid;
}

我认为,将 created_at 更改为 last_used_at 将完全符合我的需要,但问题是如何做到这一点? 当然,我不想编辑供应商文件。

到目前为止我已经尝试过:

  • 我创建了一个自定义中间件来检查 last_used_at 值,但是在调用中间件时,该值已经设置为当前时间。
  • 我将 AuthServiceProvider 中的自定义验证添加到 boot() 方法,在该方法中我对 last_used_at 值进行了检查。 这次我得到了想要的值,但在此之前执行了 Guard。 因此,首先检查来自守卫的 created_at_value ,并且在执行我的自定义验证时令牌无效。

您可以更新圣所守卫:

  1. 忽略 sanctum 服务提供者自动发现。 Go 到您的 composer.json 文件并将 Laravel\Sanctum\SanctumServiceProvider 添加到 dont-discover 数组:
"extra": {
    "laravel": {
        "dont-discover": [
            "Laravel\\Sanctum\\SanctumServiceProvider"
        ]
    }
},
  1. 添加您的自定义扩展避难所服务提供商
php artisan make:provider ExtendedSanctumServiceProvider
  1. 扩展基础 SanctumServiceProvider 并覆盖 createGuard 方法,添加您的自定义 Guard。 这看起来像下一个例子

<?php

namespace App\Providers;

use App\Guards\SanctumGuard;
use Illuminate\Auth\RequestGuard;
use Illuminate\Support\Facades\Log;
use Laravel\Sanctum\SanctumServiceProvider;

class ExtendedSanctumServiceProvider extends SanctumServiceProvider
{
    /**
     * Register the guard.
     *
     * @param  \Illuminate\Contracts\Auth\Factory  $auth
     * @param  array  $config
     * @return RequestGuard
     */
    protected function createGuard($auth, $config)
    {
        return new RequestGuard(
            new SanctumGuard($auth, config('sanctum.expiration'), $config['provider']),
            request(),
            $auth->createUserProvider($config['provider'] ?? null)
        );
    }
}
  1. 创建您在下面定义的自定义 sanctum Guard,扩展基础 Sanctum Guard 并覆盖 isValidAccessToken 方法
<?php

namespace App\Guards;

use Laravel\Sanctum\Guard as BaseSanctumGuard;
use Laravel\Sanctum\Sanctum;

class SanctumGuard extends BaseSanctumGuard
{
    /**
     * Determine if the provided access token is valid.
     *
     * @param  mixed  $accessToken
     * @return bool
     */
    protected function isValidAccessToken($accessToken): bool
    {
        if (! $accessToken) {
            return false;
        }

        $last_used_at = $accessToken->last_used_at;
        if(!$last_used_at) $last_used_at = $accessToken->created_at;

        $isValid =
            (! $this->expiration || $last_used_at->gt(now()->subMinutes($this->expiration)))
            && $this->hasValidProvider($accessToken->tokenable);

        if (is_callable(Sanctum::$accessTokenAuthenticationCallback)) {
            $isValid = (bool) (Sanctum::$accessTokenAuthenticationCallback)($accessToken, $isValid);
        }

        return $isValid;
    }
}
  1. 在 app.php > 'providers' 中注册您的服务提供商
/*
* Application Service Providers...
*/
...
App\Providers\AppServiceProvider::class,
App\Providers\ExtendedSanctumServiceProvider::class,
.
.
.

有了这一切,你准备好了 go

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM