When utilizing rtk query, you have the ability to enhance your apiSlice baseQuery function to handle authentication errors and redirect accordingly. Here is a suggestion:
Begin by creating a base query that checks for specific error statuses such as 401:
// Attempt to execute the request, if it fails due to authorization issues, logout and redirect to login.
const baseQueryWithAuth: BaseQueryFn = async (args, api, extraOptions) => {
const result = await baseQuery(args, api, extraOptions);
if (result.error?.status === 403 || result.error?.status === 401) {
// Unauthorized access, redirect to login page.
// If JWT exists, update the access token here
localStorage.removeItem(TOKEN_KEY_IN_LOCAL_STORAGE);
Router.replace('/auth/login');
}
return result;
};
In the above code snippet, the removal of the token is referred to as a logout because the token is already invalid in the database, hence only deletion is necessary on the front-end without requiring an invalidate request.
The mentioned baseQuery
can be implemented like so:
const baseUrl = `${process.env.NEXT_PUBLIC_API_PROTOCOL}://${process.env.NEXT_PUBLIC_API_HOST}/api`;
const TOKEN_KEY_IN_LOCAL_STORAGE = 'SavedToken';
const baseQuery = fetchBaseQuery({
baseUrl,
// credentials: 'include',
prepareHeaders: (headers) => {
// Retrieve the authentication token from local storage if available
const token = localStorage.getItem(TOKEN_KEY_IN_LOCAL_STORAGE);
if (token) {
headers.set('Authorization', token);
} else {
Router.replace('/auth/login');
}
return headers;
},
});
Once you have a functional base query with authentication support, you can proceed to create the main rtk query apiSlice
for your project:
// Create API
export const apiSlice = createApi({
baseQuery: baseQueryWithAuth,
tagTypes: ['tag1', 'tag2', 'tag3'],
endpoints: (_builder) => ({}),
});