首页 > 其他分享 >前端无痛刷新Token

前端无痛刷新Token

时间:2022-10-03 12:02:32浏览次数:54  
标签:请求 res Instance Token 刷新 无痛 config


前端无痛刷新Token

这个需求场景很常见,几乎很多项目都会用上,之前项目也实现过,最近刚好有个项目要实现,重新梳理一番。

需求

对于需要前端实现无痛刷新Token,无非就两种:

  1. 请求前判断Token是否过期,过期则刷新
  2. 请求后根据返回状态判断是否过期,过期则刷新

处理逻辑

实现起来也没多大差别,只是判断的位置不一样,核心原理都一样:

  1. 判断​​Token​​是否过期
  1. 没过期则正常处理
  2. 过期则发起刷新​​Token​​的请求
  1. 拿到新的​​Token​​保存
  2. 重新发送​​Token​​过期这段时间内发起的请求

重点:

  • 保持​​Token​​过期这段时间发起请求状态(不能进入失败回调)
  • 把刷新​​Token​​后重新发送请求的响应数据返回到对应的调用者

实现

  1. 创建一个flag​​isRefreshing​​ 来判断是否刷新中
  2. 创建一个数组队列​​retryRequests​​来保存需要重新发起的请求
  3. 判断到​​Token​​过期
  1. ​isRefreshing = false​​​ 的情况下 发起刷新​​Token​​的请求
  1. 刷新​​Token​​​后遍历执行队列​​retryRequests​
  1. ​isRefreshing = true​​​ 表示正在刷新​​Token​​​,返回一个​​Pending​​​状态的​​Promise​​​,并把请求信息保存到队列​​retryRequests​​中
import axios from "axios";
import Store from "@/store";
import Router from "@/router";
import { Message } from "element-ui";
import UserUtil from "@/utils/user";// 创建实例
const Instance = axios.create();
Instance.defaults.baseURL = “/api”;
Instance.defaults.headers.post[“Content-Type”] = “application/json”;
Instance.defaults.headers.post[“Accept”] = “application/json”;// 定义一个flag 判断是否刷新Token中
let isRefreshing = false;
// 保存需要重新发起请求的队列
let// 请求拦截
Instance.interceptors.request.use(async function(config) {
Store.commit(“startLoading”);
const userInfo = UserUtil.getLocalInfo();
if (userInfo) {
//业务需要把Token信息放在 params 里面,一般来说都是放在 headers里面
config.params = Object.assign(config.params ? config.params : {}, {
appkey: userInfo.AppKey,
token: userInfo.Token
});
}
return config;
});// 响应拦截
Instance.interceptors.response.use(
async function(response) {
Store.commit(“finishLoading”);
const res = response.data;
if (res.errcode == 0) {
return Promise.resolve(res);
} else if (
res.errcode == 30001 ||
res.errcode == 40001 ||
res.errcode == 42001 ||
res.errcode == 40014
) {
// 需要刷新Token 的状态 30001 40001 42001 40014
// 拿到本次请求的配置
let config = response.config;
// 进入登录页面的不做刷新Token 处理
if (Router.currentRoute.path !== “/login”) {
if (!isRefreshing) {
// 改变flag状态,表示正在刷新Token中
isRefreshing = true;
// 刷新Token
return Store.dispatch(“user/refreshToken”)
.then(res {
// 设置刷新后的Token
config.params.token = res.Token;
config.params.appkey = res.AppKey;
// 遍历执行需要重新发起请求的队列
retryRequests.forEach(cb cb(res));
// 清空队列
retryRequests = [];
return Instance.request(config);
})
.catch(() => {
retryRequests = [];
Message.error(“自动登录失败,请重新登录”);
const code = Store.state.user.info.CustomerCode || “”;
// 刷新Token 失败 清空缓存的用户信息 并调整到登录页面
Store.dispatch(“user/logout”);
Router.replace({
path: “/login”,
query: { redirect: Router.currentRoute.fullPath, code: code }
});
})
.finally(() => {
// 请求完成后重置flag
isRefreshing = false;
});
} else {
// 正在刷新token,返回一个未执行resolve的promise
// 把promise 的resolve 保存到队列的回调里面,等待刷新Token后调用
// 原调用者会处于等待状态直到 队列重新发起请求,再把响应返回,以达到用户无感知的目的(无痛刷新)
return new Promise(resolve {
// 将resolve放进队列,用一个函数形式来保存,等token刷新后直接执行
retryRequests.push(info {
// 将新的Token重新赋值
config.params.token = info.Token;
config.params.appkey = info.AppKey;
resolve(Instance.request(config));
});
});
}
}
return new Promise(() => {});
} else {
return Promise.reject(res);
}
},
function(error) {
let err = {};
if (error.response) {
err.errcode = error.response.status;
err.errmsg = error.response.statusText;
} else {
err.errcode = -1;
err.errmsg = error.message;
}
Store.commit(“finishLoading”);
return Promise.reject(err);
}
);export default Instance;

复制代码

文笔不怎么样,谅


标签:请求,res,Instance,Token,刷新,无痛,config
From: https://blog.51cto.com/ruan365392777/5730067

相关文章

  • Spring boot+VUE使用token实现登录验证及退出
    Springboot+VUE实现token验证Vue+SpringBoot实现token认证主要可分为六步:1.前端登录,post用户名和密码到后端。2.后端验证用户名和密码,若通过,生成一个token返回给前端......
  • 如何实现 Token 无感刷新 All In One
    如何实现Token无感刷新AllInOne实现原理要实现无感刷新,接口一般会返回两个token:一个access_token用于授权验证一个refresh_token用于更新access_tokenrefs......
  • 加工中心刀库复归及刀库表刷新操作
    立式加工中心刀库复归及刀库表刷新操作这种操作久经考验干什么?主要用于:1、换刀过程中系统出现报警,刀臂卡刀了怎么办?2、换刀过程中按了复位或急停,刀臂甩出停在一半怎么办?3、......
  • 跨模态学习能力再升级,EasyNLP电商文图检索效果刷新SOTA
    简介: 本⽂简要介绍我们在电商下对CLIP模型的优化,以及上述模型在公开数据集上的评测结果。最后,我们介绍如何在EasyNLP框架中调用上述电商CLIP模型。作者:熊兮、欢......
  • vue 动态路由刷新页面404
    1.如果你的静态路由最后有如下代码://404pagemustbeplacedattheend!!!{path:"*",redirect:"/404",hidden:true},2.如果你的路由有一部分是动态获取......
  • sqlmap绕过token保护
    1、演示页面<?phpsession_start();if(isset($_SESSION['token'])&&isset($_POST['username'])){if(empty($_POST['token'])||$_POST['token']!=$_SESSION['token']){......
  • burpsuite intruder 小技巧之 自动token验证
    第一步:标记爆破点,及爆破方式:爆破方式选择:pitch-fork:可以在每个爆破点载入不同的字典,但是在过程中多个字典均顺序执行。 第二步:配置payloads 针对token配置迭代调用;第三步:......
  • 跨模态学习能力再升级,EasyNLP电商文图检索效果刷新SOTA
    作者:熊兮、欢夏、章捷、临在导读多模态内容(例如图像、文本、语音、视频等)在互联网上的爆炸性增长推动了各种跨模态模型的研究与发展,支持了多种跨模态内容理解任务。在这些跨......
  • 引用 | pip install keybert | ERROR: Could not build wheels for tokenizers which
    window10安装keybert出错以下错误:runningbuild_extrunningbuild_rusterror:can'tfindRustcompilerIfyouareusinganoutdatedpipversion,it......
  • JS 刷新页面所有方法
    window.location.reload();使用window.open()弹出的弹出窗口,刷新父窗口非模态刷新父页面:window.opener.location.reload()使用window.showDialog弹出的模式窗口模态刷新父......