【问题标题】:How can I do refresh auth token logiс with axios for multiple requests?如何使用 axios 为多个请求刷新身份验证令牌逻辑?
【发布时间】:2022-01-30 17:34:54
【问题描述】:

我试图这样做,但是对于三个请求,它会发送三个刷新请求:

  • 1、2、3 失败并显示 401
  • 刷新成功,1成功,2,3失败
  • 刷新成功,2成功,3失败
  • 刷新成功3成功

我不能在移动设备上放置那么多负载(即使只有 3 次刷新而没有“重新失败”)

这是我的代码:

function requestRefreshToken(refreshToken, accessToken) {
  return axios
    .create({
      baseURL: apiUrl + Endpoints.AUTH.REFRESH,
      skipAuthRefresh: true,
      headers: {
        'Accept-Language': 'ru',
        'User-Agent': `${Platform.OS} ${packageJson.version}`,
        Authorization: accessToken,
      },
    })
    .post(
      '',
      {
        grant_type: GrantTypes.REFRESH_TOKEN,
        refresh_token: refreshToken,
        client_id: Client.id,
        client_secret: Client.secret,
      },
      { validateStatus },
    );
}

const refreshAuthLogic = async failedRequest =>
  Keychain.getCredentials()
    .then(old => requestRefreshToken(old.refreshToken, old.accessToken))
    .then(({ data: credentials }) => {

      failedRequest.config.headers.Authorization = `${credentials.token_type} ${
        credentials.access_token
      }`;

      return Keychain.setCredentials(credentials);
    });

createAuthRefreshInterceptor(axios, refreshAuthLogic, {
  retryInstance: axios,
  skipWhileRefreshing: true,
  onRetry: function(config) {
    return Keychain.getCredentials().then(({ accessToken }) =>
      axios({
        ...config,
        header: { ...config.headers, Authorization: accessToken },
      }),
    );
  },
});

axios.interceptors.response.use(
  r => r,
  request => {
    if (request.response.status === 401) {
      return Keychain.getCredentials().then(({ accessToken }) =>
        axios({
          ...request.config,
          header: { ...request.config.headers, Authorization: accessToken },
        }),
      );
    }
  },
);

【问题讨论】:

  • 你确定额外的请求不是由你在代码末尾的第二个拦截器触发的吗?使用 skipWhileRefreshing 设置为 true 时不应发生这种情况
  • 另外,访问令牌也应该通过拦截器添加到请求中。这样,每当重试请求时,拦截器就会绑定正确的令牌。当然,您需要将令牌存储在状态或变量中,这应该不是问题。
  • 如果我删除额外的拦截器并将skipWhileRefreshing设置为false,我们将得到下一个:1)所有3个请求都失败,401 2)刷新成功3)第一次成功,另外两个失败或者第一次成功两次其他人因失败而陷入困境

标签: axios refresh-token


【解决方案1】:

解决了这个问题!似乎没有失败的请求队列就没有办法解决它(https://gist.github.com/mkjiau/650013a99c341c9f23ca00ccb213db1c

【讨论】:

    【解决方案2】:

    这是我实现它的一种快速方法。 我发现推理代码更简单一些。 我已经从这个解决方案中改编了它: HERE

    let refreshTokenPromise: null | Promise < any > ;
    
    instance.interceptors.response.use(r => {
      const {
        data
      } = r;
      if (data.errors && data.errors[0].message === "AUTH_EXPIRED") {
        if (!refreshTokenPromise) {
          refreshTokenPromise = fetchRefreshToken().then(data => {
            refreshTokenPromise = null;
            return data;
          });
        }
    
        return refreshTokenPromise.then(token => {
          if (r.config.headers) r.config.headers["Authorization"] = token;
          return instance.request(r.config);
        });
      }
      return r;
    });
    

    【讨论】:

      猜你喜欢
      • 2018-05-06
      • 2020-03-06
      • 1970-01-01
      • 2016-07-17
      • 2012-02-07
      • 2017-11-08
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多