Nuxt刷新后Store登录状态丢失 本地存储/Cookie数据仍留存
问题根因
Vuex 状态存储在前端运行时内存中,页面刷新时 JS 执行上下文会完全重建,内存中的 Store 状态会被重置为代码里定义的初始值。你当前仅在登录成功时把认证数据写入了 localStorage 和 Cookie,但应用初始化阶段没有把本地存储中有效的认证信息重新注入 Store,因此刷新后读取 Store 状态会判定为未登录,和 mutation 提交逻辑、本地存储写入逻辑无关。
修复方案
可根据项目技术选型二选一实现即可。
方案1:原生实现(无需额外依赖)
直接在 Store 初始化阶段读取本地存储的有效认证数据,作为初始状态注入,修改 Store 目录下的 index.js 即可:
import mutations from './mutations.js'; import getters from './getters.js'; // 启动时读取并校验本地存储的认证信息 const loadStoredAuth = () => { const token = localStorage.getItem('token'); const userId = localStorage.getItem('userId'); const tokenExpiration = localStorage.getItem('tokenExpiration'); const now = new Date().getTime(); // 信息缺失或token已过期,清空无效存储数据,返回未登录初始状态 if (!token || !userId || !tokenExpiration || now > Number(tokenExpiration)) { localStorage.clear(); // 清空对应Cookie ['token', 'userId', 'email', 'tokenExpiration'].forEach(key => { document.cookie = `${key}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`; }); return { userId: null, token: null, didAutoLogout: false }; } // 存储信息有效,直接作为初始状态 return { userId, token, didAutoLogout: false }; }; export default { state() { return loadStoredAuth(); }, mutations, getters, actions: { // 补充自动登出逻辑,token过期时调用 setAutoLogout(context) { context.commit('setAutoLogout'); localStorage.clear(); ['token', 'userId', 'email', 'tokenExpiration'].forEach(key => { document.cookie = `${key}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`; }); } } };
注意:你当前登录逻辑中过期时间计算存在错误,如果后端返回的expiresIn单位为秒,转换为毫秒时间戳应该乘以1000,乘以5000会导致过期时间比实际值长5倍,存在token被盗用的安全风险。
方案2:正确配置Nuxt Auth模块
你之前的Nuxt Auth配置缺少必填的端点映射、存储规则配置,模块不会自动读取你手动写入的本地存储数据。完整可用的local策略配置如下,修改nuxt.config.js:
auth: { strategies: { local: { token: { property: 'token', global: true, type: 'Bearer', // 配置token存储位置 storageKey: 'token', cookie: { name: 'token', options: { path: '/' } } }, user: { property: 'userId', autoFetch: false }, endpoints: { login: { url: '/api/user/login', method: 'post' }, logout: false, user: false } } }, redirect: { login: '/login', home: '/' } }
使用该方案时,你可以删掉登录页中手动写localStorage、手动写Cookie、手动提交Store mutation的逻辑,直接调用模块封装的登录方法即可,模块会自动完成状态写入、存储持久化、请求头注入全流程:
async submitForm() { await this.$auth.loginWith('local', { data: { email: this.email, password: this.password } }); // 登录成功后跳转即可 this.$router.push('/'); }
验证步骤
- 登录成功后刷新页面,打开Vue Devtools查看Store状态,确认
token、userId字段有值 - 调用需要鉴权的接口,确认请求头自动携带正确的
Authorization字段 - 手动将localStorage中
tokenExpiration的值改为过去的时间戳,刷新页面确认会自动清空无效登录状态,跳转至登录页
内容的提问来源于stack exchange,提问作者CodeChic
相关产品推荐
相关产品推荐

