优化认证提供者组件,移除不必要的请求拦截器代码,使用useQuery简化登录状态检查,增强用户认证逻辑的清晰性和可维护性。

This commit is contained in:
zyh
2025-04-10 05:03:36 +00:00
parent 5d338ca7c5
commit 4a6aa03fff
2 changed files with 43 additions and 27 deletions

View File

@@ -113,17 +113,6 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
// 设置请求拦截器
useEffect(() => {
// console.log('token状态变化当前token:', token);
// if (token) {
// // 从localStorage中恢复token时设置全局请求头
// axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
// console.log('从状态中恢复全局Authorization头:', axios.defaults.headers.common['Authorization']);
// } else {
// // 登出时删除请求头
// delete axios.defaults.headers.common['Authorization'];
// console.log('已删除全局Authorization头');
// }
// 设置响应拦截器处理401错误
const responseInterceptor = axios.interceptors.response.use(
(response) => response,

View File

@@ -1,5 +1,6 @@
import React, { createContext, useContext, useState, useEffect } from 'react';
import axios from 'axios';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { getLocalStorageWithExpiry, setLocalStorageWithExpiry } from './utils.ts';
import type { User, AuthContextType, ThemeContextType, ThemeSettings } from '../share/types.ts';
import { ThemeMode, FontSize, CompactMode } from '../share/types.ts';
@@ -65,21 +66,40 @@ const ThemeContext = createContext<ThemeContextType | null>(null);
// 认证提供者组件
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
const [token, setToken] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [token, setToken] = useState<string | null>(getLocalStorageWithExpiry('token'));
const [isAuthenticated, setIsAuthenticated] = useState(false);
const queryClient = useQueryClient();
// 初始化时从本地存储获取用户信息和令牌
useEffect(() => {
const storedToken = getLocalStorageWithExpiry('token');
const storedUser = getLocalStorageWithExpiry('user');
if (storedToken && storedUser) {
setToken(storedToken);
setUser(storedUser);
}
setIsLoading(false);
}, []);
// 使用useQuery检查登录状态
const { isLoading: isAuthChecking } = useQuery({
queryKey: ['auth', 'status', token],
queryFn: async () => {
if (!token) {
setUser(null);
setIsAuthenticated(false);
return null;
}
try {
// 设置请求头
api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
// 获取当前用户信息
const currentUser = await AuthAPI.getCurrentUser();
setUser(currentUser);
setIsAuthenticated(true);
setLocalStorageWithExpiry('user', currentUser, 24);
return { isValid: true, user: currentUser };
} catch (error) {
// 如果API调用失败自动登出
logout();
return { isValid: false };
}
},
enabled: !!token,
refetchOnWindowFocus: false,
retry: false,
});
// 登录函数
const login = async (username: string, password: string) => {
@@ -93,6 +113,9 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
setLocalStorageWithExpiry('token', token, 24); // 24小时过期
setLocalStorageWithExpiry('user', user, 24);
// 设置请求头
api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
} catch (error) {
console.error('登录失败:', error);
throw error;
@@ -112,6 +135,10 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
setUser(null);
localStorage.removeItem('token');
localStorage.removeItem('user');
// 清除请求头
delete api.defaults.headers.common['Authorization'];
// 清除所有查询缓存
queryClient.clear();
}
};
@@ -122,8 +149,8 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
token,
login,
logout,
isAuthenticated: !!token,
isLoading
isAuthenticated,
isLoading: isAuthChecking
}}
>
{children}