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

Nuxt Auth问题:AccessToken过期跳转登录而非自动刷新

问题描述
  • 已集成@nuxtjs/auth-next@5.0.0-1648802546.c9880dc模块,采用AccessToken(有效期30分钟)+RefreshToken(有效期8小时)的令牌机制
  • 期望实现:每30分钟自动通过RefreshToken刷新AccessToken;8小时后RefreshToken过期时自动登出
  • 当前问题:AccessToken过期后直接跳转至登录页,仅用户主动操作时才会触发token更新,用户闲置时会触发登录跳转

当前配置

nuxt.config.js

auth: {
    redirect: {
        login: "/",
        logout: "/",
        callback: "/dashboard",
        home: "/dashboard",
    },
    strategies: {
        local: {
            scheme: "refresh",
            token: {
                property: "tokens.access.token",
                global: true,
                type: "Bearer",
                maxAge: 60 * 30, // 30分钟
            },
            refreshToken: {
                property: "tokens.refresh.token",
                data: "refreshToken",
                maxAge: 60 * 60 * 8 // 8小时
            },
            user: {
                property: "user",
                autoFetch: false,
            },
            endpoints: {
                login: { url: "/users/login", method: "post" },
                refresh: { url: "/users/refresh-tokens", method: "post" },
                user: false,
                logout: "",
            },
            autoLogout: true,
            tokenRequired: true,
            tokenType: 'JWT',
        },
    },
    plugins: [{ src: "~/plugins/axios.js", ssr: true }],
}

/plugins/axios.js

export default function ({ store, app: { $axios }, route, redirect }) {
  // 请求拦截:为非登录请求添加Bearer令牌
  $axios.onRequest((config) => {
   let accessToken = store.state.token;
   if (accessToken && config.url !== "/users/login") {
     config.headers.Authorization = "Bearer " + accessToken;
   }
   return config;
  });

  // 错误拦截:令牌无效或过期时跳转登录页
  $axios.onError(async (error) => {
   const statusCode = error.response ? error.response.status : -1;
   if (route.path !== "/" && statusCode === 401) {
     return redirect("/");
   }
  // return Promise.reject(error);
  });
}

解决方案

1. 完善Auth模块自动刷新配置

refresh scheme原生支持自动刷新,需补充关键配置确保生效:
在local策略中添加以下参数:

autoRefresh: true, // 显式开启自动刷新(默认已开启,可明确声明)
refreshInterval: 60 * 29 * 1000 // 提前1分钟触发刷新,单位毫秒

确保token.maxAge和refreshToken.maxAge与后端返回的令牌有效期完全一致,避免时间差导致的异常。

2. 修复Axios拦截器的401处理逻辑

当前拦截器直接跳转登录会打断Auth模块的自动刷新流程,需修改为仅在RefreshToken失效时才跳转:

$axios.onError(async (error) => {
  const statusCode = error.response ? error.response.status : -1;
  if (statusCode === 401) {
    // 检查RefreshToken是否已过期
    const isRefreshTokenExpired = store.state.auth.strategy.refreshTokenExpired();
    if (isRefreshTokenExpired && route.path !== "/") {
      await store.dispatch('auth/logout');
      return redirect("/");
    }
    // 未过期则交给Auth模块自动刷新并重试请求
    return Promise.reject(error);
  }
  return Promise.reject(error);
});

3. 添加客户端定时刷新任务(解决闲置时不刷新问题)

创建~/plugins/auth-refresh.js,在客户端定时触发token刷新:

export default function ({ store }) {
  if (!store.state.auth.loggedIn) return;

  // 计算提前1分钟刷新的间隔时间
  const tokenExpiresIn = store.state.auth.token.expiresIn;
  const refreshInterval = (tokenExpiresIn - 60) * 1000;

  const refreshTimer = setInterval(async () => {
    if (store.state.auth.loggedIn) {
      try {
        await store.dispatch('auth/refreshTokens');
      } catch (e) {
        // 刷新失败则清除定时器并登出
        clearInterval(refreshTimer);
        await store.dispatch('auth/logout');
      }
    } else {
      clearInterval(refreshTimer);
    }
  }, refreshInterval);

  // 页面卸载时清除定时器
  if (process.client) {
    window.addEventListener('beforeunload', () => {
      clearInterval(refreshTimer);
    });
  }
}

在nuxt.config.js的plugins数组中添加该插件(仅客户端运行):

plugins: [
  { src: "~/plugins/axios.js", ssr: true },
  { src: "~/plugins/auth-refresh.js", ssr: false }
]

4. 修正令牌获取方式

不要直接从store.state.token取令牌,改用Auth模块统一维护的状态:
修改Axios请求拦截器:

$axios.onRequest((config) => {
  const { token } = store.state.auth;
  if (token && config.url !== "/users/login" && config.url !== "/users/refresh-tokens") {
    config.headers.Authorization = `${token.type} ${token.value}`;
  }
  return config;
});

内容的提问来源于stack exchange,提问作者Abdul Hadi P C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:15:39