Nuxt 2中@nuxt/auth刷新/手动访问页面重定向至登录页问题
问题背景
- 技术栈:Nuxt 2 + @nuxt/auth,后端采用Node.js + Express + Passport,基于Session+Cookie实现认证
- 前端通过
http-proxy-middleware代理,后端接口可通过localhost:3000/api/...路径访问 - 后端功能正常:能创建Session,登录时返回User对象,未登录时返回401;Cookie有效期设为24小时
- 前端全局启用
auth中间件,仅登录页设置auth: false
问题现象
- 登录后可正常跳转首页、访问受保护页面
- 刷新页面或手动输入受保护页面URL(如/timeline)时,会被重定向至登录页
- 重定向到登录页后,
$auth.user能显示用户信息,$auth.loggedIn最终为true,但存在加载延迟,初始状态为false - 直接访问后端
/api/user接口能获取用户信息,确认后端处于登录状态 - 此前登出跳转问题已通过配置
auth.redirect解决,但刷新/手动访问的重定向问题仍存在
初始nuxt.config.js配置
const { createProxyMiddleware } = require('http-proxy-middleware') export default { head: { // ... }, serverMiddleware: [ createProxyMiddleware('/api', { target: 'http://localhost:3300/api', changeOrigin: true, pathRewrite: { '^/api': '/' } }), createProxyMiddleware('/uploads', { target: 'http://localhost:3300', changeOrigin: true, pathRewrite: { '^/uploads': '/uploads' } }), ], router: { middleware: ['auth'] }, css: [ '~assets/scss/main.scss', ], loading: { color: '#ef443b', }, plugins: [ '~/plugins/vuelidate' ], components: true, buildModules: [ '@nuxtjs/eslint-module', '@nuxtjs/style-resources', '@nuxtjs/fontawesome', ], modules: [ 'bootstrap-vue/nuxt', '@nuxtjs/axios', '@nuxtjs/auth', 'nuxt-precompress', ], auth: { cookie: { options: { maxAge: 24 * 60 * 60 * 1000, // 24 hrs secure: process.env.NODE_ENV && process.env.NODE_ENV === 'production', // HTTP if local, HTTPS if production }, }, strategies: { local: { token: { required: false, type: false }, endpoints: { login: { url: '/api/login', method: 'POST', propertyName: false }, logout: { url: '/api/logout', method: 'GET' }, user: { url: '/api/user', method: 'GET', propertyName: false }, }, tokenRequired: false, // tokenType: 'Bearer', }, }, }, bootstrapVue: { bootstrapCSS: false, bootstrapVueCSS: false }, fontawesome: { component: 'fa', suffix: false, icons: { regular: true, solid: true, brands: true, }, }, styleResources: { scss: [ './assets/scss/_variables.scss', './assets/scss/_mixins.scss', ], hoistUseStatements: true, }, axios: { baseURL: '/', withCredentials: true, credentials: true, }, env: { apiUrl: process.env.API_URL, }, publicRuntimeConfig: { axios: { browserBaseURL: process.env.BROWSER_BASE_URL } }, privateRuntimeConfig: { axios: { baseURL: process.env.BASE_URL } }, build: { transpile: [ 'audiomotion-analyzer' ] }, }
登出代码
methods: { logout(e) { this.$auth.logout() }, },
更新后的auth配置(解决登出跳转问题)
auth: { cookie: { options: { maxAge: 24 * 60 * 60 * 1000, // 24 hrs secure: process.env.NODE_ENV && process.env.NODE_ENV === 'production', // HTTP if local, HTTPS if production }, }, strategies: { local: { token: { required: false, type: false }, endpoints: { login: { url: '/api/login', method: 'POST', propertyName: false }, logout: { url: '/api/logout', method: 'GET' }, user: { url: '/api/user', method: 'GET', propertyName: 'user' }, }, tokenRequired: false, // tokenType: 'Bearer', }, }, redirect: { login: '/login', logout: '/login', home: '/', }, },
解决方案
问题核心是页面刷新时,@nuxt/auth的初始化逻辑先于用户信息获取请求完成,导致初始$auth.loggedIn为false,触发auth中间件的重定向。
方案1:自定义auth中间件,等待认证状态确认
- 在
middleware/auth.js创建自定义中间件:
export default async function ({ app, redirect }) { // 等待auth模块初始化并获取用户信息 await app.auth.fetchUser() // 检查登录状态,未登录则重定向到登录页 if (!app.auth.loggedIn) { return redirect('/login') } }
- 修改
nuxt.config.js中的router配置,使用自定义中间件替代默认auth中间件:
router: { middleware: ['auth'] // 此处指向自定义的middleware/auth.js }
方案2:配置auth模块自动获取用户信息
在auth配置中添加以下选项,确保刷新页面时自动拉取用户信息:
auth: { // 原有配置... fetchUserOnLogin: true, fetchUserOnRefresh: true, // 其他配置... }
方案3:检查后端Cookie设置
确认后端设置Cookie时的参数是否正确:
- 设置
sameSite: 'lax'(本地开发环境可使用该值,生产环境根据需求调整) - 确保
httpOnly: true(提升安全性) - 确认
domain设置与前端域名一致,避免跨域Cookie无法携带
额外检查点
- 确认
axios的withCredentials和credentials已设置为true(当前配置已满足) - 登录页的
auth: false配置是否正确,避免循环重定向
内容的提问来源于stack exchange,提问作者andreycwb
相关产品推荐
相关产品推荐

