Laravel Sanctum子域部署:API与SPA同根域时认证失效排查
Laravel Sanctum 子域部署登录后401问题修复方案
直接按以下顺序排查修正,覆盖你描述的所有故障场景:
- 修正Sanctum stateful域名配置
你当前SANCTUM_STATEFUL_DOMAINS仅配置了SPA域名app.domain.com,API迁移到api.domain.com后,必须将API子域也加入该列表——Sanctum的EnsureFrontendRequestsAreStateful中间件会基于该列表判断请求是否需要走Cookie/Session认证模式,不在列表内的请求会直接走Token认证逻辑,自然读不到登录态。
修改.env对应配置:
注意配置里不要加http/https前缀,本地调试使用非80/443端口时要把端口号一并写上,比如SANCTUM_STATEFUL_DOMAINS=app.domain.com,api.domain.comapp.local.test:5173。如果修改后不生效,先执行php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"发布Sanctum配置文件,确认config/sanctum.php中stateful配置项是读取env值而非写死。 - 修正CORS跨域配置
你当前allowed_origins设为['*']同时开启supports_credentials=true是不符合浏览器CORS规范的:携带Cookie等凭证的跨域请求,Access-Control-Allow-Origin响应头不能为通配符*,必须明确指定允许的前端源,否则浏览器会拦截Cookie写入,直接导致会话无法持久化(也就是你看到的每次登录新增一条Cookie的问题)。
修改config/cors.php对应配置:
本地调试时把本地SPA访问地址也加入该数组即可。'allowed_origins' => ['https://app.domain.com'], - 校验Session配置一致性
你当前SESSION_DOMAIN=.domain.com的配置是正确的(前导点表示匹配所有二级子域),额外确认两项配置:- 生产HTTPS环境下
SESSION_SECURE_COOKIE=true是正确配置,本地HTTP调试时请临时改为false,否则浏览器会拒绝在非加密连接下写入安全Cookie - 检查
config/session.php中same_site参数,跨子域场景请设置为lax,不要设为strict,否则跨子域请求不会自动携带关联Cookie
- 生产HTTPS环境下
- 校验前端请求配置
不管使用Axios还是原生fetch发起API请求,必须开启携带凭证配置:Axios设置withCredentials: true,fetch设置credentials: 'include',否则跨域请求默认不会主动携带Cookie,后端拿不到会话信息自然返回401。
所有配置修改完成后,执行php artisan config:clear清除配置缓存,同时清除浏览器本地存的所有domain.com相关旧Cookie再重新测试。
故障对应逻辑说明:
- CSRF正常、登录接口成功:说明CSRF中间件、登录接口逻辑本身无问题
- 登录后401:要么是请求没携带有效会话Cookie,要么是Sanctum没把请求判定为前端有状态请求,没启动Session认证逻辑
- 每次登录新增Cookie:是因为浏览器拦截了跨域返回的Set-Cookie头,每次请求都生成新的Session ID,没有复用已有会话
内容的提问来源于stack exchange,提问作者Garrett Sanderson
相关产品推荐
相关产品推荐

