You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt 2中@nuxt/auth刷新/手动访问页面重定向至登录页问题

Nuxt 2 + @nuxt/auth 基于Session/Cookie认证的刷新重定向问题

问题背景

  • 技术栈: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中间件,等待认证状态确认

  1. 在middleware/auth.js创建自定义中间件:
export default async function ({ app, redirect }) {
  // 等待auth模块初始化并获取用户信息
  await app.auth.fetchUser()
  
  // 检查登录状态,未登录则重定向到登录页
  if (!app.auth.loggedIn) {
    return redirect('/login')
  }
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:24:35