Laravel Sanctum未鉴权API请求生成多余会话问题排查
根因分析
- 核心触发点是
Sanctum的EnsureFrontendRequestsAreStateful中间件:只要按照官方SPA适配指南把该中间件挂载到api中间件组,所有匹配sanctum.stateful配置域名的API请求都会自动追加StartSession等web中间件,强制启用会话能力——会话启动是中间件层面的逻辑,和路由是否配置鉴权、是否公开无关,哪怕是完全不需要登录的公开接口,只要经过该中间件就会执行会话读写,没有有效会话ID时就会新建会话文件。 - 3个并发请求生成独立会话属于典型的请求竞态问题:Nuxt首屏初始化时3个接口是并行发出的,首个请求抵达后端时,浏览器还未拿到服务端返回的
laravel_session和XSRF-TOKENCookie,后续两个并发请求发出时也没有携带合法会话标识,Laravel无法识别到已有会话,就会为每个无有效会话ID的请求单独生成会话文件。所有请求返回后,浏览器只会保留优先级最高的一个Cookie,后续请求自然只会复用对应的单个会话,其余两个会话文件就成了无效垃圾数据。
排查步骤
- 校验中间件配置
打开app/Http/Kernel.php,确认api中间件组是否挂载了\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,该配置是官方要求的SPA适配项,不属于配置错误,是会话触发的前提。 - 校验前端请求时序
检查Nuxt首屏请求逻辑,确认3个公开数据接口是否在/sanctum/csrf-cookie请求完成之前就已经并发发出——正常流程需要先请求csrf初始化接口拿到会话Cookie,再发起后续业务请求,提前发出的无Cookie请求必然会触发新会话生成。 - 校验Cookie匹配规则
检查config/session.php中domain、path、same_site、secure配置项,确保和前端实际访问域名、协议完全匹配,配置不匹配会导致Cookie写入后无法被后续请求携带,反复触发新会话生成。 - 校验前端跨域配置
检查Nuxt侧请求客户端(axios/ofetch)的credentials配置,确认所有需要走Sanctum鉴权的请求都统一开启了include(对应axios的withCredentials: true),配置不一致会导致部分请求不带Cookie,触发额外会话生成。
修复方案
- 时序优化(推荐):在Nuxt的客户端初始化插件中,先
await请求/sanctum/csrf-cookie,等Cookie成功写入浏览器后再执行应用挂载、首屏接口请求逻辑,从根源上避免无Cookie的并发请求抵达后端。 - 路由拆分:将不需要鉴权、不依赖会话能力的公开API路由单独拆分路由组,不经过
EnsureFrontendRequestsAreStateful中间件,这类接口不会启动会话,自然不会生成多余会话文件。 - 垃圾回收配置:调整
config/session.php中的会话lifetime为合理值,配置定时任务触发Laravel会话垃圾回收逻辑,自动清理过期无效会话文件,避免存储被占满。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

