refresh token作用与使用方式vue2.0

通常情况来说,token失效会设计两种情况:

1.token在浏览器储存时间过长,过期失效;

2.同一个账号只能在一个浏览器登录存储token,在其他浏览器登陆上一个浏览器的账号会被抢占下线。

由于不停的更新token,对于浏览器来讲,负载是非常大的,对于用户来说,体验感也不好,试想使用手机时,每隔10分钟锁一次屏,所以我们用到另个一保存token状态的refresh token,来保持token的有效性。

一,使用场景

  1. 如果是一个前后端分离的项目,使用springsecurity+jwt这种,前端用户在登录以后,后端返回给前端一个accessToken,如果没有refresh token,又因为因为安全原因accessToken过期时间会设置的比较短,在accessToken过期以后,用户将会被强制重新登录,影响用户体验
    而如果使用refresh Token,如果用户持续地访问这个网站,他们可以一直保持登录状态,而不需要定期重新登录。

  2. 如果是业务服务器之间的相互调用,那么此时只用一个Access Token即可,强制重新登录影响不大,只不过是如果使用 Refresh Token 在获取新的 Access Token 的时候比直接重新登录会方便一小丢丢(我复制的,其实个人觉得并不方便)。

二,使用流程

  1. 登录成功获得 refresh token 并持久化
  2. 通过 refresh token 请求刷新得到 access token 并临时储存
  3. 请求业务接口使用 access token
  4. access token 过期或者快过期再次回到「 2 」
  5. refresh token 也过期则生命周期结束,需重新登录

三,代码展示(需要的友友可以直接复制拿来用)

axios.interceptors.response.use(
  response => {
    const res = response.data;
    if (response.status !== 200) {    // 错误捕获处理
      return Promise.reject(new Error(res.message || "Error"));
    }

    return res;
  },
  error => {
    if (error.response.status === 401) {
      if (!isRefreshing) {
        isRefreshing = true;
        //调接口,刷新token
        return refresh({     //  refresh是调用接口,从后台获取refresh token的方法
          refToken: window.localStorage.getItem("refreshToken")
         })
        .then(result => {
        if (result.data.access_token) {
        // 刷新成功
          window.localStorage.setItem(
           "accessToken",
            result.data.token_type + " " + result.data.access_token
          );
          window.localStorage.setItem(
            "refreshToken",
            result.data.refresh_token
           );
          error.config.headers.Authorization =
            result.data.token_type + " " + result.data.access_token;
          error.config.headers.withCredentials = true;
          requestsList.length > 0 &&
            requestsList.map(cb => {
              cb();
             });
           requestsList = []; // 注意要清空
           return axios(error.config);
         } else {
        // 刷新失败 退出登录
        window.localStorage.clear();
        router.push({
          path: "/sso-login" + `?back=${encodeURIComponent(location.href)}`
        });
         }
         })
          .catch(err => {
        //刷新失败 退出登录
           window.localStorage.clear();
            router.push({
              path: "/login",
              query: { redirect: router.currentRoute.value.fullPath }
            });
            return err;
           })
           .finally(() => {
        isRefreshing = false;
           });
      } else {
        // 正在刷新token ,把后来的接口缓冲起来
        return new Promise(resolve => {
          requestsList.push(() => {
            error.config.headers.Authorization = window.localStorage.getItem(
              "accessToken"
            );
            error.config.headers.withCredentials = true;
            resolve(axios(error.config));
          });
        });
      }
    }
    return Promise.reject(error);
  }
);

猜你喜欢

转载自blog.csdn.net/m0_56683897/article/details/131836591