How to queue requests during Axios token refresh? [closed]

2 weeks ago 15
ARTICLE AD BOX

You can solve this by using a flag to track the refreshing state and an array to store pending requests. However, managing the queue manually can get quite complex.

Full disclosure: I am the author of the library mentioned below.

I created a small utility called axios-auth-refresh-queue to automate this. It intercepts 401 errors, triggers your refresh logic, and queues all subsequent requests until the new token is ready.

Most solutions only handle requests within a single tab. However, if a user has multiple tabs open, you might end up with 'Race Conditions' where multiple tabs try to refresh the token simultaneously.

My library, axios-auth-refresh-queue, includes a Cross-tab Synchronization feature. It uses LocalStorage or BroadcastChannel to ensure that only one tab performs the refresh, while other tabs wait and then receive the new token automatically.

Example usage:

import axios from "axios"; import { applyAuthTokenInterceptor } from "axios-auth-refresh-queue"; // 1. Create your axios instance const apiClient = axios.create({ baseURL: "https://api.your-backend.com", // 👈 REPLACE THIS with your actual API URL }); // 2. Setup the interceptor applyAuthTokenInterceptor(apiClient, { headerTokenHandler: (request) => { const token = localStorage.getItem("accessToken"); if (token) { request.headers.Authorization = `Bearer ${token}`; } }, // Method to get the refresh token from your storage // (You can use localStorage, sessionStorage, or cookies here) getRefreshToken: () => localStorage.getItem("refresh_token"), // Method to call your backend to refresh the token requestRefresh: async (refreshToken) => { // ⚠️ IMPORTANT: Implement your own refresh token API logic here const response = await axios.post( "https://api.your-backend.com/auth/refresh", { token: refreshToken, } ); // Function must return this specific object structure return { accessToken: response.data.accessToken, refreshToken: response.data.refreshToken, }; }, // Callback when refresh succeeds onSuccess: (newTokens) => { // Logic to save new tokens to storage localStorage.setItem("access_token", newTokens.accessToken); if (newTokens.refreshToken) { localStorage.setItem("refresh_token", newTokens.refreshToken); } // Optional: Set default header for future requests apiClient.defaults.headers.common[ "Authorization" ] = `Bearer ${newTokens.accessToken}`; }, // Callback when refresh fails (e.g., Refresh token also expired) onFailure: (error) => { console.error("Session expired, logging out..."); localStorage.clear(); window.location.href = "/login"; // Redirect to login page }, }); export default apiClient;

You can find the full source code and documentation here: https://github.com/Eden1711/axios-auth-refresh#readme

Read Entire Article