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

Axios拦截器处理Access/RefreshToken时出现无限API调用求助

问题根源分析

当RefreshToken过期时,调用getNewAccessToken()获取新Token的请求会被Axios拦截器捕获,触发新一轮的401错误处理逻辑,进而无限重复调用刷新Token的流程,形成循环。同时,跳转登录的代码执行后未终止当前Promise链,导致错误处理仍持续运行。

修复方案

1. 让刷新Token的请求跳过拦截器

给刷新Token请求添加自定义标识,在拦截器中跳过对该请求的处理,避免递归触发错误逻辑:

修改getNewAccessToken方法:

async getNewAccessToken() {
  const data = await this.$axios.get("/auth/refresh/token", {
    // 添加自定义标识,标记此为刷新Token请求
    skipInterceptor: true
  });
  return data;
}

修改请求拦截器的onSuccess逻辑:

onSuccess: (config: InternalAxiosRequestConfig) => {
  // 跳过刷新Token请求的拦截处理
  if (config.skipInterceptor) {
    return config;
  }
  const accessToken = this.$cookieStorage.getData(COOKIE_KEY.ACCESS_TOKEN);
  if (!accessToken) {
    return config;
  }
  config.headers.Authorization = `Bearer ${accessToken}`;
  return config;
}

修改响应拦截器的onFailure逻辑,优先判断是否是刷新Token请求本身报错:

onFailure: async (error: any): Promise<any> => {
  // 若为刷新Token请求返回401,直接执行登出逻辑并终止流程
  if (error.config?.url === "/auth/refresh/token" && error.response.status === STATUS.UNAUTHORIZED) {
    this.$cookieStorage.deleteData(COOKIE_KEY.IS_LOGIN);
    this.$cookieStorage.deleteData(COOKIE_KEY.USER_INFO);
    this.$cookieStorage.deleteData(COOKIE_KEY.ACCESS_TOKEN);
    this.$cookieStorage.deleteData(COOKIE_KEY.REFRESH_TOKEN);
    window.location.replace("/login");
    return Promise.reject(error);
  }

  if (error.response.status == STATUS.UNAUTHORIZED) {
    const {
      status,
      data: { accessToken },
    } = await this.getNewAccessToken();
    
    if (status === STATUS.UNAUTHORIZED) {
      this.$cookieStorage.deleteData(COOKIE_KEY.IS_LOGIN);
      this.$cookieStorage.deleteData(COOKIE_KEY.USER_INFO);
      this.$cookieStorage.deleteData(COOKIE_KEY.ACCESS_TOKEN);
      this.$cookieStorage.deleteData(COOKIE_KEY.REFRESH_TOKEN);
      window.location.replace("/login");
      return Promise.reject(error);
    }
    if (status === STATUS.OK || status === STATUS.CREATED) {
      this.$cookieStorage.setData(COOKIE_KEY.ACCESS_TOKEN, accessToken);
      return this.$axios(error.config);
    }
  }
  return Promise.reject(error);
}

2. 修复transformResponse拦截器的onFailure方法

原方法未返回Promise,会导致错误处理异常,修改为:

onFailure(error: AxiosError) {
  return Promise.reject(error);
}

3. 删除重复的响应拦截器注册

构造函数中重复添加了transformResponse拦截器,删除重复代码:

constructor() {
  this.$axios = BaseApi.createAxios();
  const requestInterceptor = this.requestInterceptor();
  const responseInterceptor = this.responseInterceptor();
  const responseTransform = this.transformResponse();
  // 移除下面这行重复代码
  // const transformResponse = this.transformResponse();

  this.$axios.interceptors.request.use(
    requestInterceptor.onSuccess,
    requestInterceptor.onFailure
  );

  this.$axios.interceptors.response.use(
    responseInterceptor.onSuccess,
    responseInterceptor.onFailure
  );

  this.$axios.interceptors.response.use(
    responseTransform.onSuccess,
    responseTransform.onFailure
  );
}
额外优化建议
  • 添加全局锁变量,防止同时触发多次刷新Token请求,避免并发冲突。
  • 在页面组件中增加登录状态判断,状态失效时停止执行API请求逻辑。

内容的提问来源于stack exchange,提问作者Jay Choi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 05:07:49