项目中 token 处理 请求拦截器 响应拦截器

1:token是什么

   某些接口需要有权限才能请求,需要一个凭证   token 还是这个凭证

   本质是一个字符串   由后端接口提供    一般在用户登录时由后端返回

 

2:把token 保存到 vuex中

  很多中间都需要使用token   所以把token放到vuex中

   实现

// vuex

state:{
   tokenInfo:{}  //存储token的值
},
mutations:{
// 通过mutations 保存token的值

    mSetTolen(state,newTokenInfo){
     state.tokenInfo=newTokenInfo
 }
},
actions:{
  //发送 请求 获取token
    async suerLogin(conText, newTokenInfo){
      try{
       comst res = await 导入的请求方式(newTokenInfo) // newTokenInfo 传入的参数
      conText.commit('mSetTolen',res)
// res 为返回的值 内存有token 调用commit 保存得到变量中
    } catch(err){
       throw new Error(err)
    // 自定义错误  并抛出   使外面可以监听到错误
    }
  }
}


// 在组件中  点击登录发送请求  接收token

onSumit(){
// 提交事件  调用封装请求的函数
this.doLogin()
},
// 封装请求的函数
 async doLogin(){
 // 加载中的提示
 try{
  await this.$store.dispatch('suerLogin',传递的参数)
// 登录成功的提示
 } catch( err){
// 错误的提示
}

}

   注意  在vuex 中使用 async await  在组件中 也要写async await  

  原因  :   代码执行步骤如下

项目中 token 处理 请求拦截器 响应拦截器_第1张图片

3:请求拦截器 ( token的自动添加)

import store from '@/store/index.js'  //获取vuex

request.interceptors.request.use(function (config) {

// 保存token 到一个变量
  const token = store.state.tokenInfo.token
// 判断 vuex中是否由token    由则自动添加到所有请求中
  if (token) {
      //  添加token
    config.headers.Authorization = `Bearer ${token}`
  }

4: 保存用户数据  

方法与保存token基本一致    但要注册单独的模块  vuex的 modules 

  模块中添加namespaced: true    组件调用时 ('模块名/方法名')

5:响应拦截器 (处理401 未登录引起的错误)

       refresh_token  用于请求token  可以保存很长时间

       encodeURIComponent() 浏览器的API 对特殊字符进行编码

import router from '../router/auth.js'  // 路由
import store from '../store/index.js'   // vuex

// 响应拦截器
request.interceptors.response.use(
  // 参数1 获取到的数据处理
  function (response) {
    return response // response 请求到的数据
  },
  // 参数2 错误处理
  async function (error) {
    console.dir(error) // 控制台显示错误

    // 如果发生了错误,判断是否是401
    if (error.response.status === 401) {
      // 开始处理

      // 获取refresh_token
      const refreshToken = store.state.tokenInifo.refresh_token
      // 判断refresh_token 是否存在
      if (refreshToken) {
        // 存在 refresh_token   使用refresh_token获取新的token
        try {
          // 这里直接使用sxios 发送请求 不能通过请求拦截器
          const res = await axios({
            url: 'http://localhost:8000/v1_0/authorizations',
            method: 'PUT',
            headers: {
              Authorization: `Bearer ${refreshToken}`
            }
          })
          // 请求到的新token 保存到 vuex 中
          // vuex中 tokenInfo 中保存两种 token
          store.commit('mSetTolen', {
            refresh_token: refreshToken,
            token: res.data.data.token
          })
          // 重新发送被拦截的请求     error.config被拦截的请求
          return request(error.config)
        } catch (error) {
          // 请求错误

          // refresh_token过期
          // 清除vuex中的 保存token的对象
          store.commit('mSetTolen', {})
          // 去到登录页  让用户重新登录    (如果有token值,就不能到login,路由守卫中拦截)
          const backtoUrl = encodeURIComponent(router.currentRoute.fullPath)
          // router.currentRoute.fullPath 携带的发送请求页路由以及参数 '/?a=2&b=1'
          // encodeURIComponent() 浏览器的API 对特殊字符进行编码
          router.push('/login?backto=' + backtoUrl) // 跳转到登录页
          return Promise.reject(error)
        }
      } else {
        // 没有refresh_token
        // 处理方法于refresh_token过期一致
        store.commit('mSetTolen', {})
        const backtoUrl = encodeURIComponent(router.currentRoute.fullPath)
        router.push('/login?backto=' + backtoUrl)
        return Promise.reject(error)
      }
    } else {
      return Promise.reject(error)
    }
  })

跳转到登录页后 登录页面中  登录后可以跳转到原页面

项目中 token 处理 请求拦截器 响应拦截器_第2张图片

你可能感兴趣的:(项目中 token 处理 请求拦截器 响应拦截器)