Laravel Sanctum搭配NuxtJS SPA时浏览器未生成CSRF Cookie问题
问题场景
使用集成Sanctum扩展的Laravel框架搭建后端API服务,前端为独立仓库开发的NuxtJS单页应用(SPA)。按照Sanctum官方文档实现SPA认证流程时,需先请求接口获取CSRF Cookie,实际调用Sanctum内置CSRF令牌接口时返回正常响应,但浏览器始终未写入对应CSRF Cookie,控制台无任何报错;使用nuxt-auth认证模块、原生axios发起请求均复现该问题。
现有配置信息
- 域名分配:后端API服务运行地址为
publisher.local:8080,前端SPA运行地址为publisher.local:3000 - NUXT AUTH 配置:
auth: { strategies: { laravelSanctum: { provider: 'laravel/sanctum', url: 'http://publisher.local:8080', endpoints: { login: { url: '/api/v1/login', method: 'post' }, // logout: { url: '/auth/logout', method: 'post' }, // user: { url: '/auth/user', method: 'get' } } }, }, },
- AXIOS 配置:
axios: { baseURL: 'http://publisher.local:8080/api/v1', credentials: true, proxy: true, },
config/sanctum.php配置:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,local:3000', Sanctum::currentApplicationUrlWithPort() ))),
config/session.php配置:
'domain' => env('SESSION_DOMAIN', '.local'),
已尝试调整上述配置的多种参数组合与变体,均未解决问题。
根因与修复方案
按优先级排查以下配置错误,绝大多数同类问题都是以下配置项写错导致:
- Sanctum stateful 域名匹配规则不满足
Sanctum的stateful域名校验是完整匹配域名+端口,当前配置里仅添加了local:3000,没有匹配实际使用的publisher.local:3000,请求不会被识别为SPA第一方请求,响应不会携带可写入的CSRF Cookie。
修复:在.env中添加配置SANCTUM_STATEFUL_DOMAINS=publisher.local:3000,publisher.local:8080,或直接修改sanctum.php的默认域名列表,把实际使用的完整域名加端口写入即可。 - Axios 跨域Cookie配置字段写错
Nuxt/Axios模块中控制跨域请求携带Cookie、接收Set-Cookie响应头的配置项是withCredentials,不是credentials。当前配置里字段写错,导致浏览器忽略后端返回的Cookie写入指令。
修复:把axios配置中的credentials: true改为withCredentials: true。 - CSRF接口路径被API前缀污染
当前axios设置的baseURL带/api/v1前缀,但Sanctum默认的CSRF Cookie接口路径是/sanctum/csrf-cookie,无/api前缀。如果请求被baseURL拼接为/api/v1/sanctum/csrf-cookie,即使自定义路由返回204状态码,也不会走Sanctum内置的Cookie下发逻辑。
修复:在nuxt-auth的laravelSanctum策略中单独指定csrf端点地址为http://publisher.local:8080/sanctum/csrf-cookie,请求CSRF时不要拼接API前缀。 - 非HTTPS环境下开启了Secure Cookie属性
本地开发使用HTTP协议,如果session.php中secure配置项为true,浏览器会直接拒绝在非加密连接下写入Session、CSRF相关Cookie。
修复:本地开发环境在.env中设置SESSION_SECURE_COOKIE=false,生产环境部署HTTPS后再开启该配置。 - SameSite属性拦截跨端口Cookie写入
如果session.php中same_site配置为strict,同主域下跨端口的请求会被浏览器拦截Cookie写入。
修复:本地开发环境将该值设为lax,配合现有.local泛域名Session配置即可正常跨子域、跨端口共享Cookie。 - 本地域名解析校验
确认系统hosts文件中publisher.local已正确映射到本地回环地址127.0.0.1,避免前后端请求实际走了不同IP解析,导致域名不匹配无法写入Cookie。
修复验证方式:调整配置后重启Laravel服务、清空浏览器站点缓存,重新请求CSRF接口,在开发者工具Network面板中找到该请求的响应头,存在
Set-Cookie: XSRF-TOKEN=xxx字段,且Application面板Cookie列表中publisher.local域名下存在XSRF-TOKEN、laravel_session两个Cookie即为修复成功。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

