{"id":728,"hash":"ea7f59aba05afe489ad75db0c4fafad81b2c14ea0e95b1e1ad3438b80f0fbe3b","pattern":"How to handle 401 (Authentication Error) in axios and react?","full_message":"I have one file request.js which contains wrapper for axios ajax request. I am calling request function from multiple react components and when one of the request fails I want to refresh the token and retry all the failed requests again. I can use intercepters, but I don't know how to implement it. Please help.\n\nrequest.js\n\n var client = axios.create({\n   baseURL: 'http://192.168.1.3:3000',\n     headers: {\n     appID: 8,\n     version: \"1.1.0\",\n     empID: localStorage.getItem('empID'),\n     token: localStorage.getItem('accessToken')\n    }\n });\n\n const request = function(options) {\n     const onSuccess = function(response) {\n         console.debug('Request Successful!', response);\n         return response.data;\n     } \n     const onError = function(error) {\n         console.error('Request Failed:', error.config);\n         if (error.response) {\n             console.error('Status:',  error.response.status);\n             console.error('Data:',    error.response.data);\n             console.error('Headers:', error.response.headers);\n         } else {\n             console.error('Error Message:', error.message);\n         }\n\n         return Promise.reject(error.response || error.message);\n     }\n\n     return client(options)\n         .then(onSuccess)\n         .catch(onError);\n         options\n }\n\n export default request;","ecosystem":"npm","package_name":"reactjs","package_version":null,"solution":"I got it working with the following code:\n\nimport axios from 'axios';\nimport config from '../../configuration.json';\nimport qs from 'qs';\n\nconst baseURL = config['baseUrl_local'];\nlet authTokenRequest;\n\n/**\n  * @description axios instance for ajax requests\n*/ \n\nvar client = axios.create({\n    baseURL: baseURL,\n    headers: {\n        appID: 8,\n        version: \"1.1.0\",\n        empID: localStorage.getItem('empID'),\n        token: localStorage.getItem('accessToken')\n    }\n});\n\n/**\n * @description this method calls a requestNewToken method to issue a \n new token to the client\n*/ \n\n function getAuthToken() {\n   if (!authTokenRequest) {\n     authTokenRequest = requestNewToken();\n     authTokenRequest.then(resetAuthTokenRequest, resetAuthTokenRequest);\n   }\n\n   return authTokenRequest;\n }\n\n/**\n  * @description this method requests the server to issue a new token, \n  the server response is updated in local storage accessToken\n*/ \n\nfunction requestNewToken() {\n  var newToken = request({\n  method: \"post\",\n  url: '/sign-in',\n  data:  qs.stringify({\n         \"userName\":localStorage.getItem('userName'),\n         \"password\":localStorage.getItem('password')\n         })  \n  }).then((res)=>{\n  if(res.status == \"success\"){\n    localStorage.setItem('accessToken',res.data.accessToken);\n    //if featureArray is present in response object, update the \n    featureArray in local storage\n    if(res.data.features){\n      localStorage.setItem(\n      'featureArray',\n     JSON.stringify(res.data.features));\n    }\n    client = axios.create({\n     baseURL: baseURL,\n     headers: {\n          appID: 8,\n          version: \"1.1.0\",\n          empID: localStorage.getItem('empID'),\n          token: localStorage.getItem('accessToken')\n      }\n   });\n } else {\n  window.location = \"/logout\";\n }\n});\n\n return newToken;\n}\n\nfunction resetAuthTokenRequest() {\n  authTokenRequest = null;\n }\n\n/**\n  * @description if any of the API gets 401 status code, this method \n   calls getAuthToken method to renew accessToken\n  * updates the error configuration and retries all failed requests \n  again\n*/ \n\nclient.interceptors.response.use(undefined, err => {\n  const error = err.response;\n  // if error is 401 \n  if (error.status===401 && error.config && \n  !error.config.__isRetryRequest) {\n  // request for a new token\n  return getAuthToken().then(response => {\n   // update the error config with new token\n   error.config.__isRetryRequest = true;\n   error.config.headers.token= localStorage.getItem(\"accessToken\");\n   return client(error.config);\n  });\n } \n});\n\n/**\n * @description wrapper for making ajax requests\n * @param {object} object with method,url,data etc.\n*/ \n\nconst request = function(options) {\n  const onSuccess = function(response) {\n    return response.data;\n  }\n const onError = function(error) {\n  //console.error('Request Failed:', error.config);\n   if (error.response) {\n  //console.error('Status:',  error.response.status);\n  //console.error('Data:',    error.response.data);\n  //console.error('Headers:', error.response.headers);\n  } else {\n  console.error('Error Message:', error.message);\n  }\n return Promise.reject(error.response || error.message);\n }\n\nreturn client(options)\n        .then(onSuccess)\n        .catch(onError);\n        options\n}\n\nexport default request;\n\n[EDIT] Its 2019, Here is yet another implementation for the same. The above solution is great but does not work well with multiple failed request, in turn it calls getToken with the updated token as well.\n\n import axios from \"axios\";\n\n /* @internal */\n import config from \"../config\";\n import TokenService from \"./token_service\"; // Could You please provide code from this file too?\n\nclass Request {\n    constructor() {\n        this.baseURL = config.baseUrl;\n        this.isRefreshing = false;\n        this.failedRequests = [];\n        this.tokenService = new TokenService();\n        this.client = axios.create({\n            baseURL: config.apiServerBaseUrl,\n            headers: {\n               clientSecret: this.clientSecret,\n            },\n        });\n        this.beforeRequest = this.beforeRequest.bind(this);\n        this.onRequestFailure = this.onRequestFailure.bind(this);\n        this.processQueue = this.processQueue.bind(this);\n        this.client.interceptors.request.use(this.beforeRequest);\n        this.client.interceptors.response.use(this.onRequestSuccess, \nthis.onRequestFailure);\n}\n\nbeforeRequest(request) {\n    const token = TokenService.getAccessToken();\n    request.headers.Authorization = `Token ${token}`;\n    return request;\n}\n\nstatic onRequestSuccess(response) {\n    return response.data;\n}\n\nasync onRequestFailure(err) {\n    const { response } = err;\n    if (response.status === 401 && err && err.config && !err.config.__isRetryRequest) {\n        if (this.isRefreshing) {\n            try {\n                const token = await new Promise((resolve, reject) => {\n                    this.failedRequests.push({ resolve, reject });\n                });\n                err.config.headers.Authorization = `Bearer ${token}`;\n                return this.client(err.config);\n            }\n            catch (e) {\n                return e;\n            }\n        }\n        this.isRefreshing = true;\n        err.config.__isRetryRequest = true;\n        return new Promise((resolve, reject) => {\n            this.tokenService.refreshAccessToken().then((token) => {\n                this.tokenService.setAccessToken(token);\n                err.config.headers.Authorization = `Bearer ${token}`;\n                this.isRefreshing = false;\n                this.processQueue(null, token);\n                resolve(this.client(err.config));\n            }).catch((e) => {\n                this.processQueue(e, null);\n                reject(err.response);\n            });\n        });\n    }\n    throw response;\n}\n\nprocessQueue(error, token = null) {\n    this.failedRequests.forEach((prom) => {\n        if (error) {\n            prom.reject(error);\n        } else {\n            prom.resolve(token);\n        }\n       });\n        this.failedRequests = [];\n    }\n\n}\n\nconst request = new Request();\n\nexport default request.client;","confidence":0.95,"source":"stackoverflow","source_url":"https://stackoverflow.com/questions/47216452/how-to-handle-401-authentication-error-in-axios-and-react","votes":109,"created_at":"2026-04-19T04:51:33.561299+00:00","updated_at":"2026-04-19T04:51:33.561299+00:00"}