fix(auth): prevent unauthorized requests and improve logout handling

This commit is contained in:
2025-11-14 20:51:24 +08:00
parent 034c190373
commit 5bacd45419
3 changed files with 34 additions and 9 deletions

View File

@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next';
import { useForm } from 'react-hook-form';
import userService from '../services/user_service';
import { rsaPsw } from '../utils/encryption';
import { Authorization, Token, UserInfo } from '@/constants/authorization';
/**
* OAuth回调处理Hook
@@ -98,9 +99,9 @@ export const useAuth = () => {
// 登出功能
const logout = () => {
localStorage.removeItem('token');
localStorage.removeItem('Authorization');
localStorage.removeItem('userInfo');
localStorage.removeItem(Authorization);
localStorage.removeItem(Token);
localStorage.removeItem(UserInfo);
setToken(null);
setAuthorization(null);
setUserInfo(null);
@@ -191,7 +192,7 @@ export const useLogin = () => {
});
const { data: res = {}, headers } = response;
const authorization: string = headers['authorization'] ?? headers['Authorization'] ?? '';
localStorage.setItem('Authorization', authorization);

View File

@@ -18,7 +18,11 @@ export function useProfileSetting() {
const { fetchUserInfo, userInfo } = useUserData();
useEffect(() => {
fetchUserInfo();
// 仅在已登录情况下才获取用户信息避免登录页触发401导致重复跳转
const authorization = localStorage.getItem('Authorization');
if (authorization && authorization !== '') {
fetchUserInfo();
}
}, [fetchUserInfo]);
const updateUserInfo = async (newUserInfo: Partial<IUserInfo>) => {
@@ -58,6 +62,12 @@ export function useLanguageSetting() {
try {
// LanguageAbbreviation to language
const translatedLanguage = LanguageAbbreviationKeysMap[language];
const authorization = localStorage.getItem('Authorization');
// 未登录时仅本地切换语言不请求后端避免401导致跳转
if (!authorization || authorization === '') {
setLanguage(translatedLanguage);
return;
}
await updateUserInfo({ language: translatedLanguage });
setLanguage(translatedLanguage);
} catch (error) {

View File

@@ -1,4 +1,4 @@
import { Authorization } from '@/constants/authorization';
import { Authorization, Token, UserInfo } from '@/constants/authorization';
import type { ResponseType } from '@/interfaces/database/base';
import i18n from '@/locales';
import axios from 'axios';
@@ -51,10 +51,24 @@ const getAuthorization = (): string => {
return localStorage.getItem(Authorization) || '';
};
// 重定向到登录页
// 重定向到登录页(若已在登录页则不重复刷新,避免死循环)
const redirectToLogin = (): void => {
localStorage.removeItem(Authorization);
window.location.href = '/login';
try {
localStorage.removeItem(Authorization);
localStorage.removeItem(Token);
localStorage.removeItem(UserInfo);
const currentPath = `${window.location.pathname}${window.location.search}`;
logger.info('redirectToLogin() invoked', { currentPath });
// 已在登录页则不再刷新,交由路由守卫处理
if (window.location.pathname === '/login') {
logger.info('Already on /login, skip hard redirect');
return;
}
window.location.href = `/login?redirect=${encodeURIComponent(currentPath)}`;
} catch (e) {
logger.warn('redirectToLogin() exception fallback to /login');
window.location.href = '/login';
}
};
// 转换对象键为snake_case