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

React Native过期Token并发请求处理问题求助

解决React Native多并行请求下Token重复刷新问题

你的核心问题是多个并行请求同时触发了Token刷新逻辑,原因是refreshAuthToken的锁机制没有真正拦住后续请求——当第一个请求还在刷新Token时,userAccess状态还没更新,后续请求进入getCredentials时依然判断Token过期,从而重复调用refreshToken,导致旧的refreshToken被作废后,后续请求再用它刷新就会报错。

修正方案

1. 把刷新锁逻辑移到getCredentials内部

让getCredentials自身成为单入口,确保同一时间只有一个刷新请求发起,其他请求复用同一个刷新Promise:

// 模块级/全局变量,避免组件重渲染时被重置
let refreshTokenPromise: Promise<string> | null = null;

const getCredentials = useCallback(async () => {
  // 优先复用正在进行的刷新请求
  if (refreshTokenPromise) {
    return await refreshTokenPromise;
  }

  const currentUnixTimestamp = moment().unix();
  if (userAccess.expirationTimeStamp < currentUnixTimestamp) {
    console.log('refreshing token', userAccess.accessObject?.refreshToken);
    // 赋值全局Promise,让所有后续请求等待同一个任务
    refreshTokenPromise = refreshToken()
      .then(newToken => {
        // 关键:刷新成功后必须更新userAccess状态
        // 这里需要调用更新userAccess的方法(比如setUserAccess),把新的token和过期时间存进去
        return newToken;
      })
      .finally(() => {
        // 刷新完成后清空Promise,允许下次正常触发刷新
        refreshTokenPromise = null;
      });
    return await refreshTokenPromise;
  }

  return userAccess.accessObject?.accessToken || '';
}, [userAccess, refreshToken]);

2. 确保Axios拦截器正确调用getCredentials

所有请求必须通过拦截器统一获取Token,避免绕开锁逻辑:

axiosInstance.interceptors.request.use(async (config) => {
  const token = await getCredentials();
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

3. 处理刷新失败的边界情况

如果刷新Token失败(比如refreshToken本身过期),需要及时清除本地凭证并跳转登录,避免无限循环:

refreshTokenPromise = refreshToken()
  .then(newToken => {
    // 更新userAccess状态
    return newToken;
  })
  .catch(error => {
    // 刷新失败:清除本地存储的凭证,跳转到登录页
    clearCredentials();
    navigation.navigate('Login');
    throw error; // 抛出错误让请求拦截器捕获
  })
  .finally(() => {
    refreshTokenPromise = null;
  });

为什么原代码无效?

原代码中refreshAuthToken的锁是在调用getCredentials之前,但多个并行请求会同时进入refreshAuthToken——此时refreshTokenPromise还未被赋值,所以多个请求都会执行getCredentials。而此时userAccess还是旧的过期状态,每个getCredentials都会判断Token过期,进而重复触发refreshToken,导致后续请求使用已作废的refreshToken报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 07:07:49