- 移除 VITE_SERVICE_LOGOUT_CODES 中的 1002023000 状态码 - 将 VITE_SERVICE_EXPIRED_TOKEN_CODES 从 1002023001 改为 1002023000 - 修改 fetchRefreshToken 函数使用 params 传递 refreshToken 并设置 skipAuth - 添加 skipAuth 配置选项避免给公开接口带上过期 access 头 - 实现 notifySessionExpired 函数确保并发请求只弹一次会话失效提示 - 在登录成功后复位会话失效标志以支持下次正常提示 - 更新 handleExpiredRequest 使用 refreshTokenPromise 替代 refreshTokenFn
88 lines
2.3 KiB
TypeScript
88 lines
2.3 KiB
TypeScript
import { useAuthStore } from '@/store/modules/auth';
|
|
import { localStg } from '@/utils/storage';
|
|
import { fetchRefreshToken } from '../api';
|
|
import { SESSION_EXPIRED_MESSAGE } from './error-message';
|
|
import type { RequestInstanceState } from './type';
|
|
|
|
export function getAuthorization() {
|
|
const token = localStg.get('token');
|
|
const Authorization = token ? `Bearer ${token}` : null;
|
|
|
|
return Authorization;
|
|
}
|
|
|
|
/** 刷新 token */
|
|
async function handleRefreshToken() {
|
|
const rToken = localStg.get('refreshToken') || '';
|
|
const { error, data } = await fetchRefreshToken(rToken);
|
|
if (!error) {
|
|
localStg.set('token', data.token);
|
|
localStg.set('refreshToken', data.refreshToken);
|
|
return true;
|
|
}
|
|
|
|
notifySessionExpired();
|
|
|
|
return false;
|
|
}
|
|
|
|
export async function handleExpiredRequest(state: RequestInstanceState) {
|
|
if (!state.refreshTokenPromise) {
|
|
state.refreshTokenPromise = handleRefreshToken();
|
|
}
|
|
|
|
const success = await state.refreshTokenPromise;
|
|
|
|
setTimeout(() => {
|
|
state.refreshTokenPromise = null;
|
|
}, 1000);
|
|
|
|
return success;
|
|
}
|
|
|
|
// 会话失效一次性锁:保证 N 个并发请求只弹一次 toast、只 resetStore 一次
|
|
let sessionExpiredNotified = false;
|
|
|
|
/**
|
|
* 通知用户会话已失效,弹一次 toast 后清状态、跳登录。
|
|
*
|
|
* 多个并发请求触发时只会真正执行一次;登录成功后由 resetSessionExpiredFlag() 复位。
|
|
*/
|
|
export function notifySessionExpired() {
|
|
if (sessionExpiredNotified) return;
|
|
sessionExpiredNotified = true;
|
|
|
|
window.$message?.error(SESSION_EXPIRED_MESSAGE);
|
|
|
|
const { resetStore } = useAuthStore();
|
|
resetStore();
|
|
}
|
|
|
|
/** 登录成功后复位一次性锁,让下一次会话失效仍能正常提示 */
|
|
export function resetSessionExpiredFlag() {
|
|
sessionExpiredNotified = false;
|
|
}
|
|
|
|
export function showErrorMsg(state: RequestInstanceState, message: string) {
|
|
if (!state.errMsgStack?.length) {
|
|
state.errMsgStack = [];
|
|
}
|
|
|
|
const isExist = state.errMsgStack.includes(message);
|
|
|
|
if (!isExist) {
|
|
state.errMsgStack.push(message);
|
|
|
|
window.$message?.error({
|
|
message,
|
|
onClose: () => {
|
|
state.errMsgStack = state.errMsgStack.filter(msg => msg !== message);
|
|
|
|
setTimeout(() => {
|
|
state.errMsgStack = [];
|
|
}, 5000);
|
|
}
|
|
});
|
|
}
|
|
}
|