Syncing Auth State Across Tabs with Axios
This article explains how to manage and synchronize user authentication state across multiple browser tabs using the Axios HTTP client. Because Axios is purely a request library without native cross-tab awareness, synchronizing authentication tokens, logins, and logouts requires integrating Axios interceptors with browser-level APIs like the Storage Event, the Broadcast Channel API, or the Web Locks API.
The Role of Axios in Multi-Tab Authentication
Axios does not maintain state across browser tabs by itself. Instead,
it serves as the operational layer that attaches authentication
credentials (such as JWT bearer tokens) to outgoing requests and reacts
to authentication failures (such as 401 Unauthorized
responses).
To achieve cross-tab synchronization, developers use Axios request and response interceptors as the bridge between in-memory application state and browser-level communication channels.
Core Synchronization Mechanisms
Synchronizing authentication with Axios relies on pairing interceptors with one of several browser APIs.
1. The Storage Event Listener
When tokens are stored in localStorage, changes made in
one tab trigger a storage event in all other open tabs of
the same origin.
- How it works: When Tab A logs in or updates a
token, it writes the new value to
localStorage. Tab B detects thestorageevent, updates its local memory, and ensures subsequent Axios calls use the updated credentials. - Logout Synchronization: If a user logs out in Tab
A, removing the token from
localStoragetriggers an event in Tab B. Tab B clears its state and redirects the user to the login screen, preventing unauthorized Axios requests.
2. The Broadcast Channel API
The BroadcastChannel API allows direct, low-latency
messaging between browser contexts (tabs, windows, iframes, and
workers).
- How it works: A dedicated channel (e.g.,
auth_channel) is created across all tabs. When an authentication event occurs, messages likeAUTH_LOGOUTorTOKEN_REFRESHEDare broadcasted. - Axios Integration: When a tab refreshes an expired token via an Axios response interceptor, it broadcasts the new token to all tabs. Other tabs update their active Axios default headers or state variables without needing to re-fetch the token themselves.
3. Synchronizing Token Refreshes with Web Locks
A common issue in multi-tab setups is the "refresh race condition," where multiple tabs make requests simultaneously with an expired token, causing each tab to trigger a separate refresh token request.
To resolve this with Axios:
- Catching the Expiry: An Axios response interceptor
intercepts a
401status code. - Acquiring a Lock: The tab uses
navigator.locks.request('auth_refresh_lock', ...)to ensure only one tab executes the refresh call. - Execution: The leader tab uses Axios to request a new access token from the server.
- Broadcast & Retry: Once resolved, the leader updates storage, broadcasts the new token to waiting tabs, and retries the failed Axios request. The other tabs release their locks, read the newly issued token, and retry their pending Axios calls.
Dynamic Token Resolution in Axios Interceptors
To prevent tabs from sending stale tokens, Axios request interceptors should dynamically retrieve the token before every outgoing HTTP request rather than relying on a static default header configured at initialization:
axios.interceptors.request.use((config) => {
// Always fetch the latest token from storage or current memory
const token = localStorage.getItem('access_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});By querying the updated storage value on each execution, Axios immediately inherits any credential updates performed by adjacent browser tabs.