Reputation: 61
I am having a problem with the RTK query interceptor, I implemented Automatic re-authorization by extending fetchBaseQuery per RTK query documentation and now I have a problem that if multiple requests get fired and the token is not valid all of them will get 401 as a response and all of them will try to refresh a token which will result in the first one being successful and other ones will fail and then the else will fire and return the user to log in screen.
Is there a way to prevent this?
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
Upvotes: 4
Views: 3857
Reputation: 44086
One possible solution for that would be to use a mutex. We were discussing a possible solution for that in 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: () => ({}),
});
Upvotes: 5