You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Sanctum令牌过期机制及删除后仍存在问题咨询

Laravel Sanctum 令牌过期的实现方式

咱先把第一个问题拆解清楚,Sanctum让令牌过期主要有这么几种玩法:

  • 手动删除令牌:就像你用的$user->currentAccessToken()->delete();,这是直接针对当前使用的令牌执行删除操作;如果要批量干掉用户所有令牌,用$user->tokens()->delete();就行。默认情况下Sanctum用的是软删除,所以执行delete后令牌不会从数据库直接消失,只是被标记为已删除;要是你改了模型或者迁移用硬删除,那令牌就直接从表中移除了。
  • 主动吊销令牌:调用令牌实例的revoke()方法,这个操作不会删令牌,而是把它的expires_at字段设为当前时间之前的时刻,让令牌立刻过期失效,适合那种不想删记录但要禁用令牌的场景。
  • 创建时指定过期时间:生成令牌的时候用expiresAt()方法设置有效期,比如:
    $token = $user->createToken('my-api-token')
                  ->expiresAt(now()->addDays(3))
                  ->plainTextToken;
    
    这样令牌3天后就自动过期了。
  • 全局默认过期配置:在config/sanctum.php里找到expiration选项,设置一个数值(单位是分钟),所有没单独指定过期时间的令牌都会用这个默认有效期。

为啥删了令牌还在表中,但Auth::check()返回false?

这个问题确实容易让人困惑,咱一步步捋:

首先,Sanctum默认的PersonalAccessToken模型是带SoftDeletes trait的,对应的迁移文件里也有deleted_at软删除字段。你说你的表没有这个字段,那大概率是你自定义了迁移或者移除了模型里的软删除特性?

不过不管怎样,你执行$user->currentAccessToken()->delete();后Auth::check()返回false,说明令牌已经被判定为无效了,哪怕它还在数据库里。Sanctum验证令牌的时候,会做这几件事:

  1. 查数据库里的有效令牌:它会找和请求令牌匹配的记录,同时:
    • 如果开了软删除,会自动排除deleted_at不为null的记录;
    • 如果没开软删除,正常来说delete()会硬删令牌,但你说令牌还在,那要么是你模型重写了delete()方法,要么是你误把revoke()当成了delete()——毕竟revoke()只会改expires_at为过去的时间,令牌还在表中,但已经失效了。
  2. 检查过期时间:哪怕令牌存在,只要expires_at的时间比当前时间早,Sanctum就会直接判定它无效,不会通过身份验证。

简单说,Sanctum判断令牌有效与否,不是只看“有没有在表中”,还要看它是不是被标记删除(软删除)、有没有过期。只要这两个条件有一个不满足,验证就失败,Auth::check()自然返回false。

内容的提问来源于stack exchange,提问作者Inigo EC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:22:40