首页 > 解决方案 > 使用 axios/axios-auth-refresh 的 JWT 刷新令牌流问题

问题描述

(我在这里阅读了许多类似的问题,并且大多数/所有人都说要对刷新令牌请求使用不同的 axios 实例(与 API 请求相比)。但是,我不清楚它是如何工作的,因为我正在使用axios-auth-refresh来自动刷新访问令牌。)

我正在为后端 API 请求使用基于 JWT 的身份验证流程的应用程序。一般流程运行良好;登录后,用户会获得一个长期刷新令牌和短期访问令牌。使用 axios 的axios-auth-refresh插件,我可以在访问令牌过期时自动刷新它。

我的问题是,当刷新令牌过期时,我无法捕获错误并将用户重定向以重新进行身份验证。我尝试过的任何方法都无法捕捉到错误。自动刷新挂钩的(当前)代码是:

const refreshAuth = (failed) =>
  axios({ method: "post", url: "token", skipAuthRefresh: true })
    .then(({ status, data: { success, accessToken } }) => {
      console.warn(`status=${status}`);
      if (!success) Promise.reject(failed);

      processToken(accessToken);
      // eslint-disable-next-line no-param-reassign
      failed.response.config.headers.Authorization = `Bearer ${accessToken}`;
      return Promise.resolve();
    })
    .catch((error) => console.error("%o", error));
createAuthRefreshInterceptor(axios, refreshAuth);

在刷新令牌过时或丢失的情况下,我既看不到控制台行,也看不到块status=xxx中错误对象的转储。catch()

此处的实际文件在 GitHub 上,尽管它与上面的工作版本略有不同。主要是,在 GH 版本中,钩子调用axios.post("token").then(...)上面我正在进行更明确的调用以添加skipAuthRefresh参数。添加它让我在控制台中获得了更详细的错误跟踪,但我仍然没有通过catch().

我已经尝试了所有我能想到的东西......有什么东西会跳出来作为我缺少的东西吗?

兰迪

(已编辑以确保 GitHub 链接指向存在问题的文件版本。)

标签: javascriptaxiosjwt

解决方案


自发布此消息以来,我已经设法解决了这个问题并提出了一个可行的解决方案。

解决方案的关键实际上在于使用不同的 axios 实例来调用更新刷新令牌。我创建了第二个模块来封装第二个不会获取axios-auth-refresh模块创建的拦截器的 axios 实例。在解决了最初导致的一些无意的循环依赖问题之后,我发现当刷新令牌本身过时或丢失时,我可以看到 axios 抛出异常。

(有趣的是,这导致了另一个问题:一旦我发现刷新令牌不再有效,我需要注销用户并让他们返回登录屏幕。因为这里的应用程序是一个 React 应用程序,所以身份验证正在使用只能在组件中调用的自定义钩子进行处理。但是,我已将所有 API 调用抽象到一个非 React 模块中,以便我可以封装诸如添加Authorization标头、基本 URL 等内容。在那个级别,我无法运行 auth 挂钩来访问注销逻辑。我通过在我用于所有 API 调用onError的查询对象(一个react-query对象)上放置一个默认处理程序来解决这个问题。)


推荐阅读