Facundo La Rocca
Facundo La Rocca

Reputation: 3866

axios keeps returnin 401 when renewing token

I am having issues after renewing the token to re-execute the original request. Basically, after the new token has been obtained and properly set, when I try to execute the original request I keep getting Request failed with status code 401.

I am sure I am messing up the promise, but I can't realize where the problem is

// axiosWrapper.js

import axios from 'axios';
import authenticationApi from './authentication';

const baseURL = 'http://apiurl/';
const axiosWrapper = axios.create({
  baseURL,
});

axiosWrapper.interceptors.response.use(
  response => response,
  error => {
    if (error.response.status === 401) {
      return authenticationApi.auth()
        .then(res => {
          if (res.status === 200) {
            setToken(res.data.token);
            return axios.request(error.config);
          }
        })
        .catch(err => {
          console.log(err); // Request failed with status code 401
        });
    }

    return Promise.reject(error);
  },
);

axiosWrapper.interceptors.request.use(async config => {
  if (config.url === '/auth') {
    return config;
  }

  var token = await getToken();
  config.headers.Authorization = token ? 'Bearer ${token}' : '';

  return config;
});

export default axiosWrapper;

// authentication.js
import axiosWrapper from './axiosWrapper';

export default {
  auth: () => axiosWrapper.post('auth', {apiKey: 'apiKey'}),
};

Upvotes: 1

Views: 378

Answers (1)

Facundo La Rocca
Facundo La Rocca

Reputation: 3866

After carefully debugging and refactoring, I realized the issue was on the promise I was returning instead of returning the result of the new request. It turned out that using async/await keywords made it much more clear. So here is how it looks like after refactoring:

const baseURL = 'http://server/';
const axiosWrapper = axios.create({
  baseURL,
});

axiosWrapper.interceptors.response.use(
  response => response,
  async error => {
    if (error.response.status === 401) {
      if (error.config._retry) {
        return Promise.reject(error);
      }

      error.config._retry = true;

      const authResult = await authenticationApi.auth()
      if (authResult.status === 200) {
        await setToken(authResult.data.token); // Set token to storage
        error.config.headers.Authorization = `Bearer ${authResult.data.token}`;

        const requestResult = await axios.request(error.config);
        return requestResult; // Return the result of the request, not the promise
      }
    }

    return Promise.reject(error);
  },
);

axiosWrapper.interceptors.request.use(async config => {
  if (config.url === 'auth') {
    return config;
  }

  const token = await getToken(); // Get token from storage
  config.headers.Authorization = token ? `Bearer ${token}` : '';

  return config;
});

Upvotes: 1

Related Questions