token与refresh_token

说明:  登录成功之后服务器会返回两个 `token` 相关的数据
    1. token

  •  用来做身份认证的,好让服务器知道你是谁,但是token是有有效期的,在本项目中,有效期为 `2小时`
  •  每过 2 小时,`token` 会失效,需要重新登录
  •  用户视角:操作着页面,突然需要重新登录,用户体验不好
  •   模拟 token 失效: 找到 `开发者工具 => Application => localstorage => 对应的 token => 双击 token 的值进行编辑`

    2.refresh_token

  • `refresh_token` 用于在token过期后,获取新的用户token
  •  它的有效期为14天

结论:
    为了解决 `token` 每 `2` 小时过期一次的问题:
    监听服务器的响应是否出错
    判断是否是 toke 失效
      * 是:通过 `refresh_token` 获取新的 `token`
      * 否:不用理会

 1.token失效--------解决方案

 一旦 `token` 过期,使用这个过期的 `token` 时,服务器会报错,错误的状态码为: `401`
 解决方案(响应拦截器中):
  * 判断错误的状态码是否为 `401`
  * 如果是 `401` ,根据 `refresh_token` 得到新的 `token`
  * 再将原来的 `token` 替换掉

const instance = axios.create({
  baseURL: "http://toutiao.itheima.net/",
});
// 再创建一个 axios 的副本(负责更新 token)
const refInstance = axios.create({
  baseURL: "http://toutiao.itheima.net/",
});


// 响应拦截器
instance.interceptors.response.use(
  (response) => {
    return response;
  },
  async (error) => {
    console.dir(error);
    const status = error.response.status;
    if (status === 401) {
      console.log(status);
      const refresh_token = store.state.token.refresh_token;
      console.log(refresh_token);
      try {
        const res = await refInstance({
          url: "/v1_0/authorizations",
          method: "PUT",
          headers: {
            Authorization: `Bearer ${refresh_token}`,
          },
        });
        console.log(res);
        store.commit("setToken", {
          token: res.data.data.token,
          refresh_token: refresh_token,
        });
        console.log("更新成功");
        return instance(error.config);
      } catch (e) {
        Toast.fail("登录已经过期");
        router.push("/login");
        return Promise.reject(new Error("refresh_token 已过期"));
      }
    }
    return Promise.reject(error);
  }
);

**注意点:**

* 在更新 `token` 时,一定不能使用之前 `instance` 实例来发送请求:
    * 原因:它有一个请求拦截器,这个请求拦截器,会将设置好的 `Authorization` 覆盖为失效的    `token`
    * 解决方案:再创建一个 `axios` 副本对象,这个副本对象只用来更新 `token`

2.token失效-------无感刷新

* 解决了 `token` 失效之后,页面依旧无法正常请求数据
* 手动刷新页面之后,功能才能正常
* 手动刷新页面用户体验不好
* `token` 更新之后,重新请求之前出错的请求

  return instance(error.config);

 3.token失效--------解决refresh_token失效

 当token和refresh_token全部失效是,跳转到登陆页面,给出失效提示,重新登录。

 方法:

     * 使用`try catch` 包裹更新 `token`的代码
     * 在 `catch` 中跳转到登录页面 

 try {
        const res = await refInstance({
          url: "/v1_0/authorizations",
          method: "PUT",
          headers: {
            Authorization: `Bearer ${refresh_token}`,
          },
        });
        console.log(res);
        store.commit("setToken", {
          token: res.data.data.token,
          refresh_token: refresh_token,
        });
        console.log("更新成功");
        return instance(error.config);
      } catch (e) {
        Toast.fail("登录已经过期");
        router.push("/login");
        return Promise.reject(new Error("refresh_token 已过期"));
      }

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值