sanctum 对 spa 认证默认采用 session + csrf 模式,而非纯 token;必须先调用 get /sanctum/csrf-cookie 获取 xsrf-token cookie,再发带 credentials 的登录请求,否则因缺失 csrf 校验返回 419。

Sanctum 对 SPA 的认证不是“发个 token 就完事”,它默认走的是 session + CSRF 路线,而不是纯 token 认证。如果你在 Vue/React 前端调用 /login 一直 419 或 401,大概率是漏了 CSRF 预检或跨域凭据没开——不是代码写错了,是流程卡在了 HTTP 协议层。
为什么 /sanctum/csrf-cookie 必须先调一次?
Sanctum 不靠前端传 X-XSRF-TOKEN 头来校验,而是依赖浏览器自动携带的 XSRF-TOKEN cookie。这个 cookie 只有服务端在响应 /sanctum/csrf-cookie 时才会 set,且只对同源或显式允许的 allowed_origins 生效。
- 不调这一步,后续所有带 session 的请求(比如
Auth::attempt())都会因缺少 CSRF 校验失败,返回419 Status - 该接口必须用
GET,且不能加auth:sanctum中间件(否则形成死循环) - 确保
config/cors.php中'supports_credentials' => true,且'allowed_origins'明确列出前端地址(如http://localhost:5173),不能写* - 前端 axios 实例需开启凭据:
axios.defaults.withCredentials = true;fetch 则要加credentials: 'include'
登录后为什么还要手动 createToken?
Sanctum 的 SPA 模式本身不强制生成 personal access token——Auth::attempt() 成功后,只要会话维持、CSRF 有效,后续请求走 auth:sanctum 中间件就能通过。但你如果想让前端「记住登录状态」(比如刷新页面不掉登),就得自己管理 token。
- 仅靠 session cookie 在某些场景下不可靠:PWA 离线缓存、Safari 的 ITP 限制、或用户清除了 cookies
-
$user->createToken('spa')->plainTextToken返回的是明文 token,应只在登录成功响应中一次性返回,**绝不存进 cookie** - 前端收到后存在
localStorage或pinia,并在后续请求头中带上:Authorization: Bearer {token} - 此时后端不再依赖 session,而是走 Sanctum 的 token 解析路径,所以中间件仍为
auth:sanctum,无需改写
auth:sanctum 中间件到底做了什么?
它不是单一逻辑,而是按顺序尝试两种认证方式:先查 cookie session,再查 Authorization header 中的 Bearer token。顺序不可逆,也不能拆开用。
- 当请求来自你自己的 SPA(满足
EnsureFrontendRequestsAreStateful的域名判断),它优先走session分支,验证laravel_session和XSRF-TOKEN - 若 session 无效或缺失,它 fallback 到
PersonalAccessToken表查 Bearer token,这就是为什么你能在登录后手动存 token 并继续用同一中间件 - 别试图把
auth:sanctum和auth:web混用——前者专为 API 设计,后者依赖 session 且不校验 CSRF,混用会导致 419 或静默失败 - 确保
app/Http/Kernel.php的'api'中间件组里包含\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,否则 SPA 请求压根不会进入 session 分支
最常被忽略的点:CSRF cookie 的 SameSite 和 Secure 属性必须和你的部署环境匹配。开发时设 'same_site' => 'lax'、'secure' => false;生产 Nginx 后端用 HTTPS 时,secure 必须为 true,否则浏览器拒绝发送 cookie,整个认证链就断了。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











