FG
๐Ÿ’ป Software๐Ÿ”Œ APIs & SDKs

Interceptors - how to prevent intercepted messages from resolving as error

Fresh3 days ago
Mar 14, 20260 views
Confidence Score57%
57%

Problem

I'm trying to make an interceptor for 401 responses that result from expired token. Upon interception I want to login and retry the requests with the new token. My problem is that login is also done asynchronously, so by the time the retry happens, the original promises reject. Is there a way around that? Here's my code: [code block]

Error Output

error => { console.log('Refresh login error: ', error) }

Unverified for your environment

Select your OS to check compatibility.

1 Fix

Canonical Fix
Unverified Fix
New Fix โ€“ Awaiting Verification

Implement Token Refresh Logic in Axios Interceptor

Medium Risk

The original promises reject because the asynchronous login process for obtaining a new token does not complete before the retry attempts are made. This leads to the original request failing with a 401 error, as the interceptor does not wait for the token refresh to complete before retrying the request.

Awaiting Verification

Be the first to verify this fix

  1. 1

    Create a Token Refresh Function

    Define a function that handles the token refresh logic. This function should return a promise that resolves with the new token once the login is successful.

    javascript
    async function refreshToken() {
      const response = await axios.post('/auth/refresh');
      return response.data.token;
    }
  2. 2

    Modify the Interceptor to Handle 401 Errors

    Update the Axios interceptor to catch 401 errors and call the refreshToken function. Use a queue to manage requests that need to be retried after the token is refreshed.

    javascript
    axios.interceptors.response.use(
      response => response,
      async error => {
        const originalRequest = error.config;
        if (error.response.status === 401 && !originalRequest._retry) {
          originalRequest._retry = true;
          const newToken = await refreshToken();
          axios.defaults.headers.common['Authorization'] = 'Bearer ' + newToken;
          return axios(originalRequest);
        }
        return Promise.reject(error);
      }
    );
  3. 3

    Handle Concurrent Requests

    Implement a mechanism to handle multiple concurrent requests that may trigger the token refresh. Use a flag to prevent multiple refresh calls and queue subsequent requests until the token is refreshed.

    javascript
    let isRefreshing = false;
    let subscribers = [];
    
    function onRefreshed(token) {
      subscribers.forEach(callback => callback(token));
      subscribers = [];
    }
    
    function addSubscriber(callback) {
      subscribers.push(callback);
    }
    
    axios.interceptors.response.use(
      response => response,
      async error => {
        const originalRequest = error.config;
        if (error.response.status === 401 && !originalRequest._retry) {
          if (isRefreshing) {
            return new Promise((resolve) => {
              addSubscriber(token => {
                originalRequest.headers['Authorization'] = 'Bearer ' + token;
                resolve(axios(originalRequest));
              });
            });
          }
          originalRequest._retry = true;
          isRefreshing = true;
          const newToken = await refreshToken();
          axios.defaults.headers.common['Authorization'] = 'Bearer ' + newToken;
          onRefreshed(newToken);
          isRefreshing = false;
          return axios(originalRequest);
        }
        return Promise.reject(error);
      }
    );
  4. 4

    Test the Implementation

    After implementing the changes, test the interceptor by simulating a 401 error and ensuring that the token refresh logic works correctly and the original request is retried successfully.

    javascript
    // Simulate a request that will fail with 401
    axios.get('/protected/resource').catch(error => {
      console.log('Request failed:', error);
    });

Validation

Confirm that when a 401 error occurs, the interceptor successfully refreshes the token and retries the original request without rejecting the promise. Check the console logs for successful request completion.

Sign in to verify this fix

Environment

Submitted by

AC

Alex Chen

2450 rep

Tags

axioshttpapi