Nuxt(静态SSR)+Sanctum认证:刷新后$auth变量清空致登出
解决Nuxt静态SSR模式下Sanctum认证刷新后登出的问题
问题诊断
- 禁用Cookie导致会话丢失:你在Sanctum策略中设置了
cookie: false,但Sanctum依赖HTTP Cookie维护用户会话,静态SSR场景下服务器端无法直接读取客户端的localStorage/sessionStorage,没有Cookie的话,服务器无法识别已登录用户,刷新后会判定为未登录状态。 - 手动存储用户引发冲突:登录后手动调用
$auth.$storage.setUniversal存储用户,这会和auth模块自身的持久化逻辑冲突,导致用户状态在刷新后无法正确恢复。 - nuxtServerInit逻辑不完善:当前从storage手动获取用户的方式,在SSR服务器端无法获取客户端存储的数据,导致服务器端渲染的页面处于未登录状态,引发客户端与服务端状态不匹配。
解决方案
1. 修正Nuxt Auth配置(恢复Cookie支持)
修改nuxt.config.js中的Sanctum策略配置,移除cookie: false,让auth模块正确使用Cookie维护会话,同时添加上用户信息接口让auth自动获取用户:
auth: { strategies: { laravelSanctum: { provider: 'laravel/sanctum', url: process.env.apiUrl, endpoints: { csrf: { url: '/sanctum/csrf-cookie', method: 'GET' }, login: { url: '/api/login', method: 'POST' }, logout: { url: '/api/logout', method: 'POST' }, user: { url: '/api/user', method: 'GET' } }, user: { property: false, autoFetch: true } // 移除cookie: false,使用默认值true } }, redirect: { login: '/mon-compte/login', logout: '/mon-compte/login', register: '/mon-compte/register' } }
注意:需确保Laravel后端的
SANCTUM_STATEFUL_DOMAINS和SESSION_DOMAIN配置正确,允许你的Nuxt前端域名跨域访问。
2. 简化登录逻辑(移除手动存储代码)
修改login.vue,删除手动存储用户的代码,让auth模块自动处理用户状态持久化:
await axios.get(`${process.env.apiUrl}/sanctum/csrf-cookie`) try { await this.$auth.loginWith('laravelSanctum', { data: { email: this.userLogin.login.email, password: this.userLogin.login.password, } }) // 无需手动setUser和存储,auth模块会自动处理 } catch (error) { this.userLogin.messageError = 'Wrong credentials' // ...其他错误处理代码 }
3. 优化nuxtServerInit逻辑
更新store/index.js,移除手动读取storage的逻辑,让auth模块在服务器端自动通过Cookie恢复用户状态:
export const actions = { async nuxtServerInit({ commit }, { $auth }) { if ($auth.loggedIn) { await $auth.fetchUser() } } }
验证步骤
- 登录后,打开浏览器开发者工具的
Application标签,确认存在laravel_session和XSRF-TOKENCookie。 - 刷新页面,检查
$auth.user是否存在,页面是否保持登录状态。 - 验证服务器端渲染的页面是否能直接显示用户信息,而非客户端hydration后才显示。
内容的提问来源于stack exchange,提问作者Vin Parker
相关产品推荐
相关产品推荐

