reactjs - RTK查询拦截多个请求

标签 reactjs redux react-redux redux-toolkit rtk-query

我的 RTK 查询拦截器有问题,我通过扩展 fetchBaseQuery 实现了自动重新授权 RTK query documentation现在我有一个问题,如果多个请求被触发并且 token 无效,所有请求都将得到 401 作为响应,并且所有请求都将尝试刷新 token ,这将导致第一个成功,其他将失败,然后 else 将触发并返回用户登录屏幕。

有什么办法可以避免这种情况吗?

  let result = await baseQuery(args, api, extraOptions)
      if (result.error && result.error.status === 401) {
        // try to get a new token
        const refreshResult = await baseQuery(
          {
          url: `http://.../${refreshToken}`,
          method: 'POST'
          }, 
          api, 
          extraOptions
        );
        if (refreshResult.data) {
          // store the new token
          api.dispatch(tokenReceived(refreshResult.data))
          // retry the initial query
          result = await baseQuery(args, api, extraOptions)
        } else {
          api.dispatch(loggedOut())
        }
      }
      return result

最佳答案

一个可能的解决方案是使用互斥体。我们在 this github discussion 中讨论了可能的解决方案:

import { Mutex } from 'async-mutex';

const mutex = new Mutex();

const baseQueryWithReauth = async (args, api, extraOptions) => {
  await mutex.waitForUnlock();
  let result = await baseQuery(args, api, extraOptions);

  if (result.error && result.error.status === 401) {
    if (!mutex.isLocked()) {
      const release = await mutex.acquire();

      try {
        const refreshResult = await baseQuery(
          {
            url: 'auth/refresh/',
            method: 'POST',
            body: { getToken(), getRefreshToken() },
          },
          api,
          extraOptions,
        );

        if (refreshResult.data) {
          api.dispatch(tokenUpdated(refreshResult.data));

          // retry the initial query
          result = await baseQuery(args, api, extraOptions);
        } else {
          api.dispatch(logout());
        }
      } finally {
        release();
      }
    } else {
      await mutex.waitForUnlock();
      result = await baseQuery(args, api, extraOptions);
    }
  }

  return result;
};

const baseApi = createApi({
  baseQuery: baseQueryWithReauth,
  endpoints: () => ({}),
});

关于reactjs - RTK查询拦截多个请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70789043/

相关文章:

javascript - 对父组件的异步函数调用

reactjs - 如何使用react-redux-firebase从firestore获取子集合

javascript - 如何使这个 switch case 语句不那么冗长?

javascript - 使用 List 更改 ImmutableJS 嵌套对象并返回整个状态(Redux)

typescript - 使用 connect 时 redux-thunk 类型错误

javascript - Aurelia + Redux 性能

javascript - React-Redux 的 connect() 方法抛出 TypeError

javascript - 如何使用map将数据从reactJs上的组件传递到另一个组件?

javascript - 当我只更改一个子值时,如何停止重新渲染 React 渲染函数中的所有子项?

javascript - 将 prop 值从登录组件向下传递到路由组件