Automating access token refreshing via interceptors in axios

I may have found a way much simpler to handle this : use axios.interceptors.response.eject() to disable the interceptor when I call the /api/refresh_token endpoint, and re-enable it after.

The code :

/**
 * Wrap the interceptor in a function, so that i can be re-instantiated
 */
function createAxiosResponseInterceptor() {
    const interceptor = axios.interceptors.response.use(
        (response) => response,
        (error) => {
            // Reject promise if usual error
            if (error.response.status !== 401) {
                return Promise.reject(error);
            }

            /*
             * When response code is 401, try to refresh the token.
             * Eject the interceptor so it doesn't loop in case
             * token refresh causes the 401 response.
             *
             * Must be re-attached later on or the token refresh will only happen once
             */
            axios.interceptors.response.eject(interceptor);

            return axios
                .post("/api/refresh_token", {
                    refresh_token: this._getToken("refresh_token"),
                })
                .then((response) => {

                    saveToken();
                    error.response.config.headers["Authorization"] =
                        "Bearer " + response.data.access_token;
                    // Retry the initial call, but with the updated token in the headers. 
                    // Resolves the promise if successful
                    return axios(error.response.config);
                })
                .catch((error2) => {
                    // Retry failed, clean up and reject the promise
                    destroyToken();
                    this.router.push("/login");
                    return Promise.reject(error2);
                })
                .finally(createAxiosResponseInterceptor); // Re-attach the interceptor by running the method
        }
    );
}
createAxiosResponseInterceptor(); // Execute the method once during start

Above code will:

  • intercept calls which are returned with a https status code 401
  • eject the interceptor, preventing infinite loop
  • Fetch a new token
  • duplicate and modify the initial request, by replacing the old with the new token
  • retry the initial request with the new token in the header
  • re-attach the interceptor after the retry request, regardless of the outcome.

Leave a Comment