fix(web): align auth contract with api

This commit is contained in:
Xiaoxia AI
2026-06-22 07:12:53 +08:00
parent 45f15c1866
commit 02d8000202
4 changed files with 59 additions and 41 deletions
+37 -4
View File
@@ -11,9 +11,13 @@ export interface LoginRequest {
export interface LoginResponse {
access_token: string;
refresh_token: string;
refresh_token?: string | null;
token_type: string;
expires_in: number;
user_id: string;
email: string;
username: string;
display_name: string;
}
export interface RegisterRequest {
@@ -25,13 +29,42 @@ export interface RegisterRequest {
export interface User {
id: string;
user_id: string;
email: string;
username: string;
display_name: string;
is_email_verified: boolean;
created_at: string;
email_verified: boolean;
created_at?: string;
}
interface UserResponse {
id?: string;
user_id?: string;
email: string;
username: string;
display_name: string;
is_email_verified?: boolean;
email_verified?: boolean;
created_at?: string;
}
const normalizeUser = (data: UserResponse): User => {
const userId = data.id ?? data.user_id ?? '';
const emailVerified = data.is_email_verified ?? data.email_verified ?? false;
return {
id: userId,
user_id: userId,
email: data.email,
username: data.username,
display_name: data.display_name,
is_email_verified: emailVerified,
email_verified: emailVerified,
created_at: data.created_at,
};
};
// 登录
export const login = async (data: LoginRequest): Promise<LoginResponse> => {
const response = await apiClient.post('/auth/login', data);
@@ -51,8 +84,8 @@ export const logout = async (): Promise<void> => {
// 获取当前用户
export const getCurrentUser = async (): Promise<User> => {
const response = await apiClient.get('/auth/me');
return response.data;
const response = await apiClient.get<UserResponse>('/auth/me');
return normalizeUser(response.data);
};
// 请求密码重置
+4 -32
View File
@@ -27,41 +27,13 @@ apiClient.interceptors.request.use(
}
);
// 响应拦截器:处理错误和 Token 刷新
// 响应拦截器:处理未授权状态
apiClient.interceptors.response.use(
(response) => response,
async (error: AxiosError) => {
const originalRequest = error.config;
// Token 过期,尝试刷新
if (error.response?.status === 401 && originalRequest) {
const refreshToken = localStorage.getItem('refresh_token');
if (refreshToken) {
try {
const { data } = await axios.post('/api/v1/auth/refresh', {
refresh_token: refreshToken,
});
// 保存新 Token
localStorage.setItem('access_token', data.access_token);
// 重试原请求
if (originalRequest.headers) {
originalRequest.headers.Authorization = `Bearer ${data.access_token}`;
}
return apiClient(originalRequest);
} catch (refreshError) {
// 刷新失败,清除 Token 并跳转登录
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
window.location.href = '/login';
return Promise.reject(refreshError);
}
} else {
// 没有 refresh token,直接跳转登录
window.location.href = '/login';
}
if (error.response?.status === 401) {
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
}
return Promise.reject(error);