vue-element-admin 如何实现token无感刷新问题?

a8jjtwal  于 4个月前  发布在  其他
关注(0)|答案(6)|浏览(39)

Question(提问)

Steps to reproduce(问题复现步骤)
Screenshot or Gif(截图或动态图)
Other relevant information(格外信息)
  • Your OS:
  • Node.js version:
  • vue-element-admin version:
vpfxa7rd

vpfxa7rd1#

当前项目需要实现token无感刷新功能,token过期时间比较短,可能2小时左右。希望大神能给出有效的实现逻辑。

以下是本人琢磨的:
请求接口时当返回的错误码为token过期时,通过 axios的await去刷新token,然后更新token,再执行上一次的请求。

问题:由于后端是通过返回http错误码的形式来实现错误信息的,后台的如果token失效后返回的是http 401错误另加一个错误码和错误信息。这种情况下不知道怎么处理,页面一直卡在加载状态。

本人的实现代码:

"@/utils/request.js"

// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    // console.log(response.headers.authorization);
    //保存token
    let token = response.headers.authorization;
    if(token){
      localStorage.setItem('token',token)
      console.log(response.headers.authorization);
      store.commit('user/SET_TOKEN', token)
      setToken(token)
    }

    return response.data;
  },
  error => {
    let response = error.response.data;

    if(response.status_code === 401 && response.code === 40100){    //token过期
      againRequest(error,'refreshToken');
    }

    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

/**
 * 刷新token同时请求上一次请求
 *
 * @param error
 * @param handle
 * @returns {Promise<AxiosResponse<T>>}
 */
async function againRequest (error,handle) {
  let response;
  switch (handle) {
    case 'refreshToken':
      response = await refreshToken();
      break;
  }

  let newToken = response.headers.authorization

  let config = error.response.config

  config.headers['Authorization'] = newToken

  if(newToken){
    store.commit('user/SET_TOKEN', newToken)
    setToken(newToken)
    localStorage.setItem('token',newToken)
  }

  return await axios.request(config) //重新发送请求

}

/**
 * 刷新token
 *
 * @returns {Promise<AxiosResponse<T> | never>}
 */
function refreshToken() {
  return axios.get(process.env.VUE_APP_BASE_API + '/refresh_token',{
    headers:{'Authorization':getToken()}
  }).then(response => {
    return response;
  }).catch(error =>{
    let response = error.response.data;
    if(response.status_code === 401 && response.code === 40110){    //token被加黑名单
      //重新登录
      MessageBox.alert('数据异常,请重新登录!', '警告', {
        confirmButtonText: '确定',
        type:'warning',
        center:true,
        callback: action => {
          store.commit('user/SET_TOKEN', '')
          store.commit('user/SET_ROLES', [])
          removeToken()
          localStorage.removeItem('token')
          router.push({ path: '/login' })
        }
      });
    }
  });
}
vlurs2pr

vlurs2pr2#

我的思路是这样的,增加一个刷新token,当然该token过期时间要比token过期时间长很多,判断逻辑思路如下:

  1. 当刷新token过期,重新登录(因为给定了很长的时间了,基于安全考虑,还是需要重新登录下)
    2.当token快要过期的时候(这个临界值自己设定的),主动请求刷新token,刷新token期间将所有api挂起,待刷新token后,执行挂起的api
2ic8powd

2ic8powd3#

我这边是思路是和服务器端的session差不多,只要刷新一直在,就一直有新的token返回......token过期时间是30分钟,,,当服务器端发现token只剩5分钟到期了,,就生成一个新的token下发到header头里面,,然后js端检测header头,,存储新的token,,下次使用新的token

大佬,能参考下您的响应header是如何截取并存储的吗?
您也用laravel-JWT?

vjrehmav

vjrehmav4#

@dougzhaug 大佬,您的 response.headers.authorization能截取的到吗?
我打印出来一直是undefined,但是控制台上的response里面确实有值的。

qnzebej0

qnzebej06#

我这边是思路是和服务器端的session差不多,只要刷新一直在,就一直有新的token返回......token过期时间是30分钟,,,当服务器端发现token只剩5分钟到期了,,就生成一个新的token下发到header头里面,,然后js端检测header头,,存储新的token,,下次使用新的token

如果同时请求了三个接口,所带的token都过期了,那服务端是不是会刷三次token?

相关问题