判断Token是否过期
- 没过期则正常处理
- 过期则发起刷新Token的请求
- 拿到新token保存,把刷新Token后重新发送请求的响应数据返回到对应的调用者
- 重新发送Token过期这段时间内发起的请求,保持Token过期这段时间发起请求状态(不能进入失败回调)
前端实现阻塞请求结果
代码示例:
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";
let isRefreshing = false;
let retryRequests = [];
Instance.interceptors.request.use(async function(config) {
Store.commit("startLoading");
const userInfo = UserUtil.getLocalInfo();
if (userInfo) {
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
) {
let config = response.config;
if (Router.currentRoute.path !== "/login") {
if (!isRefreshing) {
isRefreshing = true;
return Store.dispatch("user/refreshToken")
.then(res => {
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 || "";
Store.dispatch("user/logout");
Router.replace({
path: "/login",
query: { redirect: Router.currentRoute.fullPath, code: code }
});
})
.finally(() => {
isRefreshing = false;
});
} else {
return new Promise(resolve => {
retryRequests.push(info => {
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;
|