Reputation: 771
I have a TypeScript React front-end using RTK Query for API calls. AWS Cognito is being used on the backend for authentication. When the user's token expires I am hoping to intercept the 401, refresh the token and trigger the original request as per the example in the docs automatic-re-authorization-by-extending-fetchbasequery
However, what happens is I get a result from the baseQuery of:
status: FETCH_ERROR error: TypeError: Failed to fetch
I am expecting to receive a result.error.status of 401 so that the pathways in the logic will be met:-
const baseQuery = fetchBaseQuery({
baseUrl: `${process.env.BASE_URL}`,
prepareHeaders: (headers, { getState }) => {
const { accessToken } = (getState() as RootState).authentication.session;
if (accessToken) {
headers.set('authorization', accessToken);
}
return headers;
}
});
const baseQueryWithReauth: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (
args,
api,
extraOptions
) => {
let result = await baseQuery(args, api, extraOptions);
if (result.error && result.error.status === 401) {
const refreshResult = (await getFreshTokenFunction();
if (refreshResult) {
api.dispatch(setSession({ accessToken: refreshResult }));
// retry the initial query
result = await baseQuery(args, api, extraOptions);
} else {
api.dispatch(logout());
}
}
return result;
};
export const someApi = createApi({
reducerPath: 'someApi',
baseQuery: baseQueryWithReauth
.......
The fact the I am getting FETCH_ERROR makes me wonder about whether there is an issue with the fetch command BUT the fetch command is working perfectly for the initial request that receives the token and then gets data.
On the failed request in the network browser tab, once the token has expired, I get a 200 pre-flight and then a 401 fetch. In the console log it says "Access to fetch at *** from origin *** has been blocked by CORS policy: No 'Access-Control-Allow-Origin'". I would be surprised if it was a CORS issue though as the original requests work before the token expires.
Anyhow, any advice and help is greatly appreciated. Thanks!
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SOLUTION UPDATE 6th April 2022
In the end, the issue was that, by default, AWS APIGateway does not provide CORS response headers. So when the UI was requesting data from the API with an expired token, the response headers from the API were missing the CORS headers that the browser was looking for. The frontend logic was failing as it wasn't correctly receiving the 401 error status. Our APIGateway was configured using Serverless and it is here that the change needed to be made as follows
This ticket helped me towards the solution
Upvotes: 1
Views: 7261
Reputation: 44236
I would say that this is probably really a CORS issue. RTK Query's fetchBaseQuery
just calls fetch
, and "TypeError: Failed to fetch" is a fetch-internal error message that occurs before RTK Query can step in again to parse the response or anything like that.
Upvotes: 4