尝试刷新令牌时 Axios 拦截器无限循环

Ale*_*pov 4 javascript interceptor vue.js axios

我有一个 vue.js SPA 应用程序。我的目标是在令牌通过 axios 拦截器过期时刷新令牌。当用户向api发送请求时,我需要首先检查令牌过期时间,如果过期则刷新它,然后完成用户的请求。

我有一个刷新功能:

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

和axios请求拦截器:

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)
})
Run Code Online (Sandbox Code Playgroud)

但现在它进入无限循环。如何修复它?

小智 6

在这种情况下,你最好创建两个 axios 实例:

  • 第一个用于与授权相关的端点(不需要访问令牌的端点),例如axiosAuth. 在你的例子中 -axiosAuth.post('/api/auth/token/refresh/')
  • 第二个用于项目的授权部分,例如axiosApi。在你的例子中 -axiosApi.interceptors.request.use

您必须为第二个实例安装拦截器,在这种情况下,调用将refresh_token不会触发安装它的拦截器,正如您所期望的那样