Sanctum 的 token 过期需手动配置 expiration 并结合定时清理,不自动过期;token 存于 personal_access_tokens 表,无数据库级过期约束;前端需拦截 401 并自行实现 refresh 逻辑;后端应定期执行 sanctum:prune 命令清理僵尸记录。

Sanctum 的 token 过期和清理不是自动发生的,得靠配置、代码逻辑和定时维护三者配合。它不依赖数据库表的自动过期索引,也不像缓存那样有 TTL 自动淘汰,所有时效控制都由你主动设定和执行。
确认 token 存在哪、怎么过期
Sanctum 默认把 token 存在 personal_access_tokens 表里(不是 password_resets)。这张表没有 created_at 或 expires_at 字段的自动约束,全靠 Laravel 运行时判断:
- 过期时间由
config/sanctum.php中的'expiration'控制(单位:分钟),默认是null(永不过期),生产环境建议设为具体值,比如1440(24 小时) - token 是否过期,是在每次请求时由
Sanctum\Guard实时比对当前时间与created_at + expiration决定的 - 如果设了
'expiration' => 60,那 token 生成 60 分钟后,auth:sanctum中间件就会拒绝该请求,返回 401
前端如何应对 token 过期
用户无感知地续期,关键靠响应拦截 + refresh 逻辑,而不是等报错再跳登录页:
大模型 Token 成本节约工具。在请求到达大模型之前自动压缩 prompt 和上下文,减少 60-95% 的 token 消耗,直接降低 API 成本。支持 Claude/OpenAI/Gemini 等主流模型,提供代理模式、CLI 包装、Python SDK 和 MCP Server 四种接入方式。内置一键安...
- 后端接口响应中带上
expires_in(可选)或统一用固定策略,比如“所有 token 2 小时过期” - 前端 Axios 响应拦截器捕获 401 错误,且确认是 token 过期(不是其他认证失败)
- 此时用已保存的 refresh token(需你自行设计存储和发放机制)调用
/api/token/refresh接口 - 拿到新 access_token 后,更新本地存储,并重发原请求
- 注意:Sanctum 本身不提供 refresh endpoint,这个接口要你自己写,逻辑就是删旧 token + 创建新 token
后端怎么清理过期或无效 token
不能只靠“过期就失效”,还得定期物理清理数据库里的僵尸记录,避免表膨胀:
- 手动 SQL 清理(适合临时或低频):
DELETE FROM `personal_access_tokens` WHERE `created_at` - 更推荐用 Artisan 命令定时执行:
新建命令php artisan sanctum:prune --hours=168(对应 7 天),Laravel 自带此命令,会安全删除过期且未被显式撤销的 token - 用户登出时,别只删当前 token —— 如果要“退出所有设备”,调用
$user->tokens()->delete() - 敏感操作(如改密码、换绑)后,建议主动废除该用户所有 token:
$user->tokens()->delete()
容易忽略的关键点
很多 token 异常其实和过期无关,而是环境或配置错位:
- 检查
config/sanctum.php的'stateful'配置:API 调用必须确保你的域名不在这个数组里,否则 Sanctum 会强制走 Cookie 认证流程,导致 Bearer token 被忽略 - 确认
.env中SESSION_DOMAIN和SANCTUM_STATEFUL_DOMAINS设置正确,尤其跨子域场景 - CSRF token 缺失会导致非 GET 请求直接被拒,看起来像“认证失败”,其实根本没走到 token 校验那步
- 不要在控制器
__construct()里调用auth()->user(),中间件还没跑,永远拿不到用户










