- 一种前端处理 根据后台返的时间来刷新token(优点: 在请求前拦截,能节省请求。缺点: 需要后端额外提供一个token过期时间的字段;使用了本地时间判断,若本地时间被篡改,特别是本地时间比服务器时间慢时,拦截会失败。不采用)
- 不在请求前拦截,而是拦截返回后的数据。先发起请求,接口返回过期后,先刷新token (优点:不需额外的token过期字段,不需判断时间。缺点 会消耗多一次请求) 采用
凡是用前端直接处理的一般都不安全
import axios from "axios";
import { Message } from "element-ui";
import router from "@/router/index";
let axiosBaseUrl = import.meta.env.VITE_BASE_URL;
let isRefreshing = false;
let retryRequests = [];
const service = axios.create({
baseURL: axiosBaseUrl,
timeout: 10000,
});
service.interceptors.request.use(
(config) => {
if (localStorage.getItem("access_token")) {
let token = localStorage.getItem("access_token");
config.headers["Authorization"] = "bearer " + token;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
service.interceptors.response.use(
(response) => {
if (response.data.code == 1002) {
console.log("isRefreshing 是否更新", isRefreshing);
if (!isRefreshing) {
isRefreshing = true;
refreshTokenFun();
}
return new Promise((resolve) => {
retryRequests.push(() => {
resolve(service(response.config));
});
});
} else if (response.data.code == 1007) {
Message.error("登录失效");
router.replace({
path: "/login",
});
}
return response;
},
(error) => {
Message.error("网络不佳,请求超时!");
return Promise.reject(error);
}
);
function refreshTokenFun() {
let token = localStorage.getItem("access_token");
axios
.get(axiosBaseUrl + "/oss/v1/refresh", {
headers: {
Authorization: "bearer " + token,
},
})
.then(function(res) {
let resData = res.data;
if (resData.code == 0) {
localStorage.setItem("access_token", resData.data.access_token);
retryRequests.forEach((cb) => cb());
retryRequests = [];
isRefreshing = false;
} else if (resData.code == 1007) {
router.replace({
path: "/login",
});
}
})
.catch((e) => {
console.log("报错信息", e);
})
.finally(() => {
isRefreshing = false;
});
}