前端怎么判断token过期或无token问题

有如下两种情况会出现401错误:

  1. 未登陆用户做一些需要权限才能做的操作(例如:关注作者),代码会报出401错误。这种情况下,应该让用户回到登陆页。
  2. 登录用户的token过期了 ( token会有有效期(具体是多长,是由后端决定))

refresh_token的作用

  • 作用: 当token的有效期过了之后,可以使用它去请求一个特殊接口(这个接口也是后端指定的,明确需要传入refresh_token),并返回一个新的token回来(有效期还是2小时),以替换过期的那个token。
  • 有效期:14天。(最理想的情况下,一次登陆可以持续14天。

request的响应拦截器中:

前端怎么判断token过期或无token问题_第1张图片 

  • 对于某次请求A,如果是401错误 (2)
    • 有refresh_token,用refresh_token去请求回新的token (3)
      • 新token请求成功 (4)
        • 更新本地token (5)
        • 再发一次请求A (6)
      • 新token请求失败
        • 携带请求地址,跳转到登陆页
    • 没有refresh_token,说明没有登陆
      • 携带请求地址,跳转到登陆页

代码:

在src\utils\request.js中,补充响应拦截器。

要进行路由跳转,所以要引入/router/auth.js中的路由

import router from '../router/auth.js'


// 响应拦截器
request.interceptors.response.use(function (response) {
  console.log('响应拦截器', response)
  return response
}, async function (error) {
  // 如果发生了错误,判断是否是401
  console.dir(error)
  if (error.response.status === 401) {
    // 开始处理
    console.log('响应拦截器-错误-401')
    const refreshToken = store.state.tokenInfo.refresh_token
    // if (有refresh_token) {
    if (refreshToken) {
      // 1. 请求新token
      try {
        const res = await axios({
          url: 'http://localhost:8000/v1_0/authorizations',
          method: 'PUT',
          headers: {
            Authorization: `Bearer ${refreshToken}`
          }
        })
        console.log('请求新token', res.data.data.token)
        // 2. 保存到vuex
        store.commit('mSetToken', {
          refresh_token: refreshToken,
          token: res.data.data.token
        })
        // 3. 重发请求
        //    request是上面创建的axios的实例,它会自动从vuex取出token带上
        return request(error.config)
      } catch (error) {
        // 清除token
        store.commit('mSetToken', {})
        // 去到登录页(如果有token值,就不能到login)
        const backtoUrl = encodeURIComponent(router.currentRoute.fullPath)
        router.push('/login?backto=' + backtoUrl)
        return Promise.reject(error)
      }
    } else {
      // 去到登录页
      // 清除token
      store.commit('mSetToken', {})
      const backtoUrl = encodeURIComponent(router.currentRoute.fullPath)
      router.push('/login?backto=' + backtoUrl)
      return Promise.reject(error)
    }
  } else {
    return Promise.reject(error)
  }
})

注意点:

  1. router.currentRoute: 表示当前路由对象,如果是在.vue中,就可以用this.$route。
  2. 响应拦截器要加在axios实例 request上。
  3. 用refresh_token请求新token时,要用axios,不要用实例request
  4. 得到新token之后,再发请求时,要用request实例+

 

你可能感兴趣的:(前端,javascript,html5)