You need to enable JavaScript to run this app. 在redux-saga中如何正确使用JWT refreshToken实现accesstoken过期刷新?
优惠活动
大模型
产品
解决方案
定价
更多

在redux-saga中如何正确使用JWT refreshToken实现accesstoken过期刷新?

你的核心思路是合理的——access token过期后用refresh token换发新token再重试原请求,方向是对的,但现有实现存在几个明显缺陷,会导致逻辑不生效或者出现异常:

  • 未过滤错误类型:当前所有请求错误都会触发token刷新逻辑,比如参数错误、无权限、网络断开等非token过期的错误也会走刷新逻辑,完全不符合预期。你需要先在catch块判断错误是否为token过期导致的403,最好是后端返回专门的错误码,确认是token过期才进入刷新流程。
  • 未等待刷新流程完成就重试原请求:put 动作在saga中只是派发action,不会等待对应saga执行完成,你现在派发REFRESH_REQUEST之后立刻派发GETPOST_REQUEST,等于刷新token的请求还没返回,你就已经用旧的过期token重新发起了拉取帖子的请求,完全达不到刷新后重试的效果。
  • 未处理刷新失败的场景:如果refresh请求也失败了,比如refresh token也过期了,当前逻辑没有任何兜底处理,用户侧会出现请求无响应的情况,这种场景下应该引导用户重新登录。
  • 异步存储操作未等待完成:AsyncStorage.setItem是异步操作,当前写法没有等待存储完成就认为刷新成功,可能出现新token还没写入存储,新请求就已经读取了旧token的问题。
  • 重复刷新问题:如果同一时间有多个接口请求都返回token过期,会同时触发多次refresh请求,造成不必要的资源浪费,甚至部分后端实现中refresh token只能单次使用,多次请求会导致后续refresh直接失败。

优化后的参考实现

function* getPost(action) {
  try {
    const result = yield call(getPostAPI, action.data);
    yield put({
      type: GETPOST_SUCCESS,
      data: result.data,
    });
  } catch (err) {
    // 先判断是不是token过期的专属错误
    if (err.response?.status === 403 && err.response.data?.code === 'ACCESS_TOKEN_EXPIRED') {
      try {
        // 直接调用refresh逻辑,等待刷新完成再往下走
        const refreshResult = yield call(refreshAPI);
        // 等待token存储完成
        yield call(AsyncStorage.setItem, 'accesstoken', `${refreshResult.data.accessToken}`);
        // 重试原请求
        const retryResult = yield call(getPostAPI, action.data);
        yield put({
          type: GETPOST_SUCCESS,
          data: retryResult.data,
        });
      } catch (refreshErr) {
        // 刷新失败,抛出错误走兜底逻辑
        yield put({ type: REFRESH_FAILURE, error: refreshErr.response.data });
        // 此处补充跳转登录页的对应逻辑
      }
    } else {
      // 其他错误正常处理
      yield put({
        type: GETPOST_FAILURE,
        error: err.response.data
      })
    }
  }
}

如果需要全局所有接口都需要做token过期刷新逻辑,更推荐封装axios拦截器统一处理,不用每个接口单独写重复逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 05:54:03