Laravel Sanctum如何使令牌过期?

17

当我运行 $user->currentAccessToken()->delete(); 命令时,token 过期了,Auth::check() 的返回值为 false,这是预期的结果。

但是,当我查看 personal_access_tokens 表时,token 仍然存在。该表中没有软删除字段。Sanctum 是如何知道 token 已经过期的呢?


sanctum.php 文件中,你可以设置 'expiration' => null, - Kamlesh Paul
@KamleshPaul,是的,但这是基于创建时间而不是最后使用时间,这并不理想。如果用户在持续使用应用程序,那么拥有一天过期令牌的意义何在?如果您正在使用它并突然退出登录,那么这不是一个好的用户体验。 - Inigo EC
4个回答

28
您可以在config/sanctum.php数组节点expiration中进行设置。
/*
|--------------------------------------------------------------------------
| 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' => 60 * 24 * 7,

9
截至回答撰写时,该令牌已从数据库中删除,因此问题解决了。
Sanctum如何知道令牌是否过期非常简单:
- 令牌有一个创建日期,称之为C - config/sanctum.php中的配置数据有一个过期时间,称之为E - 您想要使用令牌的当前时间是现在,称之为N
为了检查到期情况,它会将N减去C。如果N-C小于E,则令牌尚未过期。如果大于E,则令牌已过期。
例如:
- 您在早上5点创建了一个令牌。 - 设置了5个小时的过期时间。 - 您想在早上8点通过令牌访问数据。
当您从5中减去8时,得到3。这只是自您创建令牌以来3个小时而已,比您设置的5个小时少。
如果您在11:00 AM访问数据,则时间范围变为6小时,超过了5个小时,意味着令牌已过期。

1
我已经证明了这种方法是正确的。但是,是否有可能使用last_used_at作为“C”?在这种情况下,如果令牌已经过期“E”分钟,则会被视为过期。 - grit
1
可以实现,但需要手动操作。您可以从令牌表(personal_access_tokens)开始查看,并使用逻辑和数据库查询来实现您的目标。 - Joshua Etim

4

我查看了 Sanctum 的源代码,似乎它是负责处理守卫的。

      if (! $accessToken ||
                ($this->expiration &&
                 $accessToken->created_at->lte(now()->subMinutes($this->expiration))) ||
                ! $this->hasValidProvider($accessToken->tokenable)) {
                return;
            }

这意味着验证令牌的过程如下:
  • 检查数据库中是否存在该令牌
  • 检查令牌创建日期是否超过了过期时间
  • 检查可令牌化模型是否与提供程序的模型类型匹配
  • 检查可令牌化模型是否支持API令牌
如果失败,它只是拒绝请求。不会删除令牌。
但是手动删除令牌是吊销令牌的常规方法。

您可以通过使用HasApiTokens特性提供的令牌关系从数据库中删除令牌来“撤销”令牌:


1
谢谢!但问题在于,当我执行 $user->currentAccessToken()->delete(); 时,它确实会撤销令牌,但它并没有从数据库中删除。我猜我的问题是,Sanctum 如何知道令牌已过期? - Inigo EC
1
@InigoEC,我以为那就是你问我的问题,Sanctum 不会修改token的内容,但在其过期时会拒绝请求。导致你的delete方法无法操作很可能是因为配置出现了一些问题。请确认是否在用户模型中添加了HasApiTokens特性? - PatricNox
嗨@PatricNox,那么 Sanctum 如何检查它是否过期?假设 sanctum 配置文件中的过期时间为 null,并且我手动将其过期,使用 $user->currentAccessToken()->delete();;数据库中没有类似于“expired_at”的东西。 - Inigo EC
1
过期时间在哪里定义? - trainoasis
@trainoasis 令牌过期时间在您的 Sanctum 配置文件中定义。./config/santum.php - PatricNox
显示剩余3条评论

2
下面的代码只有在 last_used_at 大于或等于 72 小时时才会返回一个有效的令牌。将其放入 AppServiceProvider 中,并将 72 更改为您希望它响应的不活动小时数。
use Laravel\Sanctum\Sanctum;
Sanctum::$accessTokenAuthenticationCallback = function ($accessToken, $isValid){
        return !$accessToken->last_used_at || $accessToken->last_used_at->gte(now()->subHours(72));
    };

谢谢兄弟!这个真是太棒了!❤ - Vaibhav K. Patil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接