Sanctum 不提供 Sanctum::login() 方法,需先 Auth::attempt() 校验,再 $user->createToken()->plainTextToken 获取明文 token;API 模式须禁用 stateful 域名、显式加 auth:sanctum 中间件;token 管理需手动操作,无自动刷新。

Sanctum 不是“调个方法就登录成功”的黑盒,它只管发 token 和验 token,登录逻辑、密码校验、错误响应都得你手写。直接抄 Passport 教程或搜到过时资料,大概率卡在 Sanctum::login() 报错或 401 无解。
为什么 Sanctum::login() 会报 “Call to undefined method”
因为这个方法根本不存在 —— Sanctum 没提供任何静态登录入口。常见错误是把 Passport 的用法套过来,或者文档看漏了关键说明。
- 正确路径是先用
Auth::attempt()校验凭证,再调$user->createToken('name') -
createToken()返回的是NewAccessToken实例,明文 token 在->plainTextToken属性里,仅此一次可见 - 别忘了在
User模型中use Laravel\Sanctum\HasApiTokens;,否则createToken()方法不可用 - 如果用了自定义 guard(比如
sanctum_api),要确认config/auth.php中该 guard 的provider指向正确的 user provider
Postman 测试始终返回 401,但 Authorization: Bearer xxx 明明填对了
Sanctum 默认优先走 Cookie 认证(用于 SPA),API 模式下必须显式禁用 stateful 行为,并严格匹配 header 格式。
- 检查
config/sanctum.php中的'stateful'数组:**删掉你的 API 域名或本地端口**(例如'localhost:3000'),否则它会强制走 session,忽略 Bearer 头 - 请求 header 必须是
Authorization: Bearer {token},注意中间是空格,不是冒号、等号或下划线 - token 值必须是
$user->createToken()->plainTextToken,不是数据库token字段里的哈希值 - Laravel 10+ 默认禁用全局中间件
EnsureFrontendRequestsAreStateful,API 路由必须显式加middleware('auth:sanctum')
登录后能取用户,但刷新 token 或登出失败
Sanctum 的 token 是独立记录在 personal_access_tokens 表里的,没有自动刷新机制,也没有“登出所有设备”这种一键操作 —— 全靠你手动管理。
- 刷新 token = 创建新 token + 主动删旧 token:
$user->currentAccessToken()->delete(); $newToken = $user->createToken('name')->plainTextToken; - 登出当前设备:调用
$user->currentAccessToken()->delete(),注意这是当前请求绑定的那个 token - 登出所有设备:用
$user->tokens()->delete(),但会清空该用户所有已发放的 token,包括其他客户端的 - token 过期时间由
config/sanctum.php的'expiration'控制(单位分钟),设为null表示永不过期 —— 生产环境慎用
最容易被忽略的是:createToken() 后不立刻取 plainTextToken,而是返回整个对象;还有就是没跑迁移导致 personal_access_tokens 表缺失,一调就报 SQL 错误。这些都不是配置问题,是代码执行链上明确的断点。


















