From 0bc8a4e9df97b36a513045dc4d03417caee5be37 Mon Sep 17 00:00:00 2001 From: xiaoxian521 <1923740402@qq.com> Date: Tue, 1 Nov 2022 16:41:31 +0800 Subject: [PATCH] release: update `3.6.3` --- mock/refreshToken.ts | 4 ++-- package.json | 2 +- public/serverConfig.json | 2 +- src/utils/auth.ts | 5 ++++ src/utils/http/index.ts | 61 ++++++++++++++++++++++++++++++++++-------------- 5 files changed, 52 insertions(+), 22 deletions(-) diff --git a/mock/refreshToken.ts b/mock/refreshToken.ts index dfdb711..87b8995 100644 --- a/mock/refreshToken.ts +++ b/mock/refreshToken.ts @@ -10,8 +10,8 @@ export default [ return { success: true, data: { - accessToken: "eyJhbGciOiJIUzUxMiJ9.admin", - refreshToken: "eyJhbGciOiJIUzUxMiJ9.adminRefresh", + accessToken: "eyJhbGciOiJIUzUxMiJ9.newAdmin", + refreshToken: "eyJhbGciOiJIUzUxMiJ9.newAdminRefresh", // `expires`选择这种日期格式是为了方便调试,后端直接设置时间戳或许更方便(每次都应该递增)。如果后端返回的是时间戳格式,前端开发请来到这个目录`src/utils/auth.ts`,把第`38`行的代码换成expires = data.expires即可。 expires: "2023/10/30 23:59:59" } diff --git a/package.json b/package.json index 6b466cf..d6e95ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pure-admin-thin", - "version": "3.6.2", + "version": "3.6.3", "private": true, "scripts": { "dev": "NODE_OPTIONS=--max-old-space-size=4096 vite", diff --git a/public/serverConfig.json b/public/serverConfig.json index 78759d6..e891bf3 100644 --- a/public/serverConfig.json +++ b/public/serverConfig.json @@ -1,5 +1,5 @@ { - "Version": "3.6.2", + "Version": "3.6.3", "Title": "PureAdmin", "FixedHeader": true, "HiddenSideBar": false, diff --git a/src/utils/auth.ts b/src/utils/auth.ts index 4aa28cc..2233923 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -70,3 +70,8 @@ export function removeToken() { Cookies.remove(TokenKey); sessionStorage.removeItem(sessionKey); } + +/** 格式化token(jwt格式) */ +export const formatToken = (token: string): string => { + return "Bearer " + token; +}; diff --git a/src/utils/http/index.ts b/src/utils/http/index.ts index 98b7f36..fc98af1 100644 --- a/src/utils/http/index.ts +++ b/src/utils/http/index.ts @@ -12,7 +12,7 @@ import { import { stringify } from "qs"; import NProgress from "../progress"; // import { loadEnv } from "@build/index"; -import { getToken } from "@/utils/auth"; +import { getToken, formatToken } from "@/utils/auth"; import { useUserStoreHook } from "@/store/modules/user"; // 加载环境变量 VITE_PROXY_DOMAIN(开发环境) VITE_PROXY_DOMAIN_REAL(打包后的线上环境) @@ -43,27 +43,43 @@ class PureHttp { this.httpInterceptorsRequest(); this.httpInterceptorsResponse(); } + + /** token过期后,暂存待执行的请求 */ + private static requests = []; + + /** 防止重复刷新token */ + private static isRefreshing = false; + /** 初始化配置对象 */ private static initConfig: PureHttpRequestConfig = {}; /** 保存当前Axios实例对象 */ private static axiosInstance: AxiosInstance = Axios.create(defaultConfig); + /** 重连原始请求 */ + private static retryOriginalRequest(config: PureHttpRequestConfig) { + return new Promise(resolve => { + PureHttp.requests.push((token: string) => { + config.headers["Authorization"] = formatToken(token); + resolve(config); + }); + }); + } + /** 请求拦截 */ private httpInterceptorsRequest(): void { PureHttp.axiosInstance.interceptors.request.use( async (config: PureHttpRequestConfig) => { - const $config = config; // 开启进度条动画 NProgress.start(); // 优先判断post/get等方法是否传入回掉,否则执行初始化设置等回掉 if (typeof config.beforeRequestCallback === "function") { - config.beforeRequestCallback($config); - return $config; + config.beforeRequestCallback(config); + return config; } if (PureHttp.initConfig.beforeRequestCallback) { - PureHttp.initConfig.beforeRequestCallback($config); - return $config; + PureHttp.initConfig.beforeRequestCallback(config); + return config; } /** 请求白名单,放置一些不需要token的接口(通过设置请求白名单,防止token过期后再请求造成的死循环问题) */ const whiteList = ["/refreshToken", "/login"]; @@ -75,21 +91,30 @@ class PureHttp { const now = new Date().getTime(); const expired = parseInt(data.expires) - now <= 0; if (expired) { - // token过期刷新 - useUserStoreHook() - .handRefreshToken({ refreshToken: data.refreshToken }) - .then(res => { - config.headers["Authorization"] = - "Bearer " + res.data.accessToken; - resolve($config); - }); + if (!PureHttp.isRefreshing) { + PureHttp.isRefreshing = true; + // token过期刷新 + useUserStoreHook() + .handRefreshToken({ refreshToken: data.refreshToken }) + .then(res => { + const token = res.data.accessToken; + config.headers["Authorization"] = formatToken(token); + PureHttp.requests.forEach(cb => cb(token)); + PureHttp.requests = []; + }) + .finally(() => { + PureHttp.isRefreshing = false; + }); + } + resolve(PureHttp.retryOriginalRequest(config)); } else { - config.headers["Authorization"] = - "Bearer " + data.accessToken; - resolve($config); + config.headers["Authorization"] = formatToken( + data.accessToken + ); + resolve(config); } } else { - resolve($config); + resolve(config); } }); },