Alexxosipov
Alexxosipov

Reputation: 1234

Axios interceptors inifinite loop when trying to refresh token

I have an vue.js SPA application. My goal is to refresh the token if it was expired via axios interceptors. When user sends the request to api, I need to check token expire time at first, and if it was expired - refresh it and then complete user's request.

I got an refresh function:

const refreshToken = () => {
  return new Promise((resolve, reject) => {
    return axios.post('/api/auth/token/refresh/').then((response) => {
      resolve(response)
    }).catch((error) => {
      reject(error)
    })
  })
}

And axios request interceptor:

axios.interceptors.request.use((config) => {
  let originalRequest = config
  if (jwt.isTokenExpired()) {
    return api.refreshToken()
      .then(res => {
        if (res.data.error == 'TOKEN_BLACKLISTED' && res.headers.authorization) {
          //get the token from headers without "Bearer " word 
          let token = res.headers.authorization.slice(7)
          //save the token in localStorage
          jwt.setToken(`"${token}"`)
          //refresh "Authorization" header with new token
          api.setHeader()
          return Promise.resolve(originalRequest)
        } else {
          jwt.destroyToken()
          jwt.destroyExpiredTime()
          store.dispatch('auth/destroyToken')
          router.push({name: 'login'})
          return Promise.reject()
        }
      })
  }
  return config
}, (err) => {
  return Promise.reject(err)
})

But now it goes to infinite loop. How to fix it?

Upvotes: 4

Views: 7654

Answers (2)

Harvey
Harvey

Reputation: 192

In this case, you'd better make two instances of axios:

  • the first for authorization-related endpoints (those that do not require an access token), for example, axiosAuth. In your example - axiosAuth.post('/api/auth/token/refresh/')
  • the second for the authorized part of your project, for example axiosApi. In your example - axiosApi.interceptors.request.use

You must install the interceptor for the second instance, in this case the call to refresh_token will not trigger the interceptor in which it is installed, as you would expect

Upvotes: 8

Gerben
Gerben

Reputation: 363

You are making a request in the interceptor. Which means that the token is stil expired when the interceptor is called on the request to the refresh url. So what you could do is to check in your interceptor if the URL is set to your refresh token URL and then just resolve the original request.

Upvotes: -1

Related Questions