h5移动端无感刷新

解决用户token过期的终极方案

为什么需要使用无感刷新?

  • 首先在移动端项目中 每个账号的信息都要出于安全考虑 需要对token设置一个过期时间 如果过期时间到了 就让用户重新登录
  • 但是这样会出现一个问题 如果过期设置的太长 比如两个星期这样的 没什么意义 设置的太短 频繁让用户登录 显然体验不好 所以必须要有一个解决的办法

实现思路大致如下

首先要有两个token
一个是真正的token
一个是refresh_token 用来获取真正token的刷新token

  • 首先在axios的拦截器里判断token有没有过期 如果过期了 响应拦截器的error里面的status返回的401(身份验证出错的状态码) 这个时候使用if判断 如果不是401代表是别的问题 我们就不处理 直接走reject
  • 如果是401的话 代表是token过期了 我们会拿着刷新token去发送ajax请求获取新的token 这个时候要使用axios的本体去发 因为axios一般都是进行了封装的 会自带原本过期的token 所以要使用axios本体去带上刷新token发送请求
  • 然后获取到新的token 调用Vuex的方法 把新的token传到里面去覆盖原来的token 这样的话Vuex里就是最新的token了 token一般都是放在vuex中的
  • 最后再次调用一下获取用户信息的请求 也就是渲染一下页面 不然第一次属性发现没有token就去获取 获取到了后虽然token是来了 但是页面还没有刷新 因为一个请求只会发一次 所以我们要获取到token后 接着再次发一个请求
function Process () {  //返回登录页面功能
  store.commit('removeToken')  //删除token
  router.push({  //跳转登录页
    path: '/login',
    query: {
      back: router.currentRoute.path  //获取回跳信息
    }
  })
  Toast.fail('用户信息过期')  //提示
}

rootAxios.interceptors.response.use(function (response) { // 响应拦截器
  return response.data // 如果响应成功了,就返回数据
}, async function (error) { // 如果响应失败了
  const { status, config } = error.response // 获取失败信息 为了拿到判断条件
  const reToken = store.state.tokenInfo.refresh_token // 拿到refresh_token 因为我们是通过刷新token去获取新token的
  if (status === 401) { // token有问题, 过期!!! ,返回401就处理
    if (reToken) { // 判断有没有刷新token
      try {
        const res = await axios({ // 如果有刷新token,就发送一个获取token的请求
          method: 'PUT',
          url: baseURL + 'v1_0/authorizations', // 根路径我们可以保存一个变量
          headers: {
            Authorization: 'Bearer ' + reToken // 参数是请求头带上刷新token
          }
        })
        store.commit('setToken', { // 获取到了新的token之后 我们要把它给Vuex 重新赋值 给tokenInfo 这都是自动完成的
          token: res.data.data.token, // 因为我们第一传给tokenInfo的时候是一个对象 所以这次我们也要传输对象
          refresh_token: reToken // 不然就没有刷新token了 所以把刷新token也带上
        })
        return rootAxios(config) // 现在有token了 我们要使用新的token去发送一个刚刚被拦截的请求 把结果return出去让await去解析res并且渲染页面
      } catch {
        Process() // 如果刷新token过期了 请求失败 就跳转login页重新登录
        return Promise.reject(error) // 返回一个reject组织请求
      }
    } else { // 如果没有刷新token 也去重新登录
      Process()
      return Promise.reject(error) //可以不加
    }
  } else { // 如果是其他的错误,就不处理
    return Promise.reject(error)
  }
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值