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

时间:2019-01-20 12:59:34

标签: 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) => {
      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)
})

但是现在它进入了无限循环。如何解决?

2 个答案:

答案 0 :(得分:1)

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

  • 第一个用于与授权相关的端点(不需要访问令牌的端点),例如 import tkinter as tk from tkinter import ttk from tkinter import * import os import webbrowser # this is the function called when the button is clicked def Jazz(): browserExe = "chrome" os.system("pkill "+browserExe) webbrowser.open("http://us4.internet-radio.com:8266/listen.pls&title=Smooth%20Jazz%20Florida&website=http://www.SmoothJazzFlorida.com") def Oldies(): browserExe = "chrome" os.system("pkill "+browserExe ) webbrowser.open("https://www.internet-radio.com/player/?mount=http://uk3.internet-radio.com:8405/live.m3u&title=Majestic%20Jukebox%20Radio%20#HIGH%20QUALITY%20SOUND&website=https://www.majesticjukeboxradio.com/") def ClassicRock(): browserExe = "chrome" os.system("pkill "+browserExe ) webbrowser.open("https://www.internet-radio.com/player/?mount=http://us4.internet-radio.com:8258/listen.pls&title=Classic%20Rock%20Florida%20HD&website=http://www.classicrockflorida.com") def Top40(): browserExe = "chrome" os.system("pkill "+browserExe ) webbrowser.open("https://www.internet-radio.com/player/?mount=http://uk7.internet-radio.com:8226/listen.pls&title=Box%20UK%20Radio%20danceradiouk&website=https://www.danceradiouk.com") root = Tk() # This is the section of code which creates the main window root.geometry('690x530') root.configure(background='#F0F8F0') root.title('Radio') # This is the section of code which creates a button Button(root, text='Jazz', bg='#F0F8FF', font=('arial', 22, 'normal'), command=Jazz).place(x=8, y=32) Button(root, text='Oldies', bg='#F0F8FF', font=('arial', 22, 'normal'), command=Oldies).place(x=8, y=96) Button(root, text='Classic_Rock', bg='#F0F8FF', font=('arial', 22, 'normal'), command=ClassicRock).place(x=8, y=160) Button(root, text='Top40', bg='#F0F8FF', font=('arial', 22, 'normal'), command=Top40).place(x=8, y=224) root.mainloop() 。 在您的示例中 - axiosAuth
  • 项目授权部分的第二个,例如 axiosAuth.post('/api/auth/token/refresh/')。 在您的示例中 - axiosApi

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

答案 1 :(得分:0)

您正在拦截器中发出请求。这意味着在对刷新url的请求中调用拦截器时,令牌已过期。因此,您可以做的是检查拦截器是否将该URL设置为刷新令牌URL,然后仅解决原始请求。