RTK查询拦截多个请求
RTK query interceptor multiple requests
我的 RTK 查询拦截器有问题,我通过扩展每个 RTK query documentation 的 fetchBaseQuery 实现了自动重新授权,现在我有一个问题,如果多个请求被触发并且令牌无效所有这些都将得到 401 作为响应,并且所有这些都将尝试刷新令牌,这将导致第一个成功,其他将失败,然后其他将触发并且 return 用户登录屏幕.
有什么办法可以避免这种情况吗?
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: () => ({}),
});
我的 RTK 查询拦截器有问题,我通过扩展每个 RTK query documentation 的 fetchBaseQuery 实现了自动重新授权,现在我有一个问题,如果多个请求被触发并且令牌无效所有这些都将得到 401 作为响应,并且所有这些都将尝试刷新令牌,这将导致第一个成功,其他将失败,然后其他将触发并且 return 用户登录屏幕.
有什么办法可以避免这种情况吗?
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: () => ({}),
});