fix(auth): 修复认证初始化与安全存储问题

- 添加authInitialized状态控制401跳转逻辑
- 实现安全存储的备份机制防止数据丢失
- 优化认证上下文初始化流程,添加取消处理
- 修复异步存储操作未处理Promise的问题
This commit is contained in:
zhang1106
2026-05-07 09:17:50 +08:00
parent fa39f2855f
commit c717ce30d6
4 changed files with 126 additions and 40 deletions
+33 -14
View File
@@ -1,5 +1,5 @@
import React, { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react';
import { authAPI } from '../api';
import { authAPI, setAuthInitialized } from '../api';
import secureStorage, { TOKEN_KEY, USER_KEY } from '../utils/secureStorage';
const AuthContext = createContext({
@@ -26,11 +26,15 @@ export const AuthProvider = ({ children }) => {
const [initialized, setInitialized] = useState(false);
useEffect(() => {
let cancelled = false;
const initializeAuth = async () => {
try {
const storedToken = await secureStorage.loadFromStorage(TOKEN_KEY);
const storedUser = await secureStorage.loadFromStorage(USER_KEY);
if (cancelled) return;
if (!storedToken) {
setToken(null);
setUser(null);
@@ -44,26 +48,41 @@ export const AuthProvider = ({ children }) => {
try {
const response = await authAPI.getProfile();
if (cancelled) return;
if (response.success) {
setUser(response.data.user);
secureStorage.set(USER_KEY, response.data.user);
await secureStorage.set(USER_KEY, response.data.user);
}
} catch (error) {
if (cancelled) return;
const status = error?.response?.status;
if (status === 401 || status === 403) {
secureStorage.remove(TOKEN_KEY);
secureStorage.remove(USER_KEY);
setToken(null);
setUser(null);
}
} catch {
secureStorage.remove(TOKEN_KEY);
secureStorage.remove(USER_KEY);
setToken(null);
setUser(null);
}
} catch {
if (cancelled) return;
setToken(null);
setUser(null);
} finally {
setLoading(false);
setInitialized(true);
if (!cancelled) {
setLoading(false);
setInitialized(true);
setAuthInitialized(true);
}
}
};
initializeAuth();
return () => {
cancelled = true;
};
}, []);
const login = useCallback(async (username, password) => {
@@ -71,8 +90,8 @@ export const AuthProvider = ({ children }) => {
const response = await authAPI.login({ username, password });
if (response.success) {
const { token: newToken, user: userData } = response.data;
secureStorage.set(TOKEN_KEY, newToken);
secureStorage.set(USER_KEY, userData);
await secureStorage.set(TOKEN_KEY, newToken);
await secureStorage.set(USER_KEY, userData);
setToken(newToken);
setUser(userData);
return { success: true };
@@ -90,8 +109,8 @@ export const AuthProvider = ({ children }) => {
if (response.success) {
const { token: newToken, user: newUser, isFirstUser, pendingApproval } = response.data;
if (newToken) {
secureStorage.set(TOKEN_KEY, newToken);
secureStorage.set(USER_KEY, newUser);
await secureStorage.set(TOKEN_KEY, newToken);
await secureStorage.set(USER_KEY, newUser);
setToken(newToken);
setUser(newUser);
}
@@ -114,7 +133,7 @@ export const AuthProvider = ({ children }) => {
const updateUser = useCallback(newUserData => {
setUser(prev => {
const updated = { ...prev, ...newUserData };
secureStorage.set(USER_KEY, updated);
secureStorage.set(USER_KEY, updated).catch(() => {});
return updated;
});
}, []);