Javascript 尝试刷新令牌时,Axios拦截器将执行有限循环

Javascript 尝试刷新令牌时,Axios拦截器将执行有限循环,javascript,vue.js,axios,interceptor,Javascript,Vue.js,Axios,Interceptor,我有一个vue.js SPA应用程序。我的目标是通过axios拦截器刷新过期的令牌。当用户向api发送请求时,我首先需要检查令牌过期时间,如果它已过期,则刷新它,然后完成用户的请求 我得到了一个刷新功能: const refreshToken = () => { return new Promise((resolve, reject) => { return axios.post('/api/auth/token/refresh/').then((response) =&

我有一个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)
    })
  })
}
和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)
})

但现在它转到无限循环。如何修复它?

您正在侦听器中发出请求。这意味着当对刷新url的请求调用拦截器时,令牌仍然过期。因此,如果URL设置为刷新令牌URL,您可以检查拦截器,然后只解析原始请求。

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

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

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

我应该在if语句中检查
jwt.isTokenExpired()
?我的意思是像
如果(jwt.isTokenExpired()&&&*url!=刷新令牌url*)
一样的问题,你找到解决方案了吗?