feat(client): 添加对authToken的处理 & 封装请求头
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
import "./App.css";
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { Routes } from "react-router-dom";
|
||||
import { handleAuthTokenFromUrl } from "./utils/auth";
|
||||
|
||||
const App: React.FC = () => {
|
||||
useEffect(() => {
|
||||
// 在组件挂载时处理URL中的authToken
|
||||
handleAuthTokenFromUrl();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="w-full h-full bg-gray-50">
|
||||
<main>
|
||||
|
||||
@@ -1 +1,79 @@
|
||||
export default {};
|
||||
import { getAuthToken } from '../utils/auth';
|
||||
|
||||
interface RequestOptions extends RequestInit {
|
||||
headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一的fetch请求封装
|
||||
* 自动添加Authorization头部
|
||||
*/
|
||||
export const apiRequest = async <T = any>(
|
||||
endpoint: string,
|
||||
options: RequestOptions = {}
|
||||
): Promise<T> => {
|
||||
const authToken = getAuthToken();
|
||||
|
||||
const url = endpoint;
|
||||
|
||||
// 准备请求头
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
};
|
||||
|
||||
// 如果有authToken,添加Authorization头
|
||||
if (authToken) {
|
||||
headers.authorization = `Bearer ${authToken}`;
|
||||
}
|
||||
|
||||
// 发起请求
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers,
|
||||
});
|
||||
|
||||
// 处理响应
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// 尝试解析JSON,如果失败则返回响应对象
|
||||
try {
|
||||
return await response.json();
|
||||
} catch {
|
||||
return response as any;
|
||||
}
|
||||
};
|
||||
|
||||
// 便捷的HTTP方法封装
|
||||
export const api = {
|
||||
get: <T = any>(endpoint: string, options?: RequestOptions): Promise<T> =>
|
||||
apiRequest<T>(endpoint, { ...options, method: 'GET' }),
|
||||
|
||||
post: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> =>
|
||||
apiRequest<T>(endpoint, {
|
||||
...options,
|
||||
method: 'POST',
|
||||
body: data ? JSON.stringify(data) : undefined,
|
||||
}),
|
||||
|
||||
put: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> =>
|
||||
apiRequest<T>(endpoint, {
|
||||
...options,
|
||||
method: 'PUT',
|
||||
body: data ? JSON.stringify(data) : undefined,
|
||||
}),
|
||||
|
||||
patch: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> =>
|
||||
apiRequest<T>(endpoint, {
|
||||
...options,
|
||||
method: 'PATCH',
|
||||
body: data ? JSON.stringify(data) : undefined,
|
||||
}),
|
||||
|
||||
delete: <T = any>(endpoint: string, options?: RequestOptions): Promise<T> =>
|
||||
apiRequest<T>(endpoint, { ...options, method: 'DELETE' }),
|
||||
};
|
||||
|
||||
export default api;
|
||||
|
||||
48
packages/client/src/utils/auth.ts
Normal file
48
packages/client/src/utils/auth.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
// 处理认证相关的工具函数
|
||||
|
||||
const AUTH_TOKEN_KEY = 'authToken';
|
||||
|
||||
/**
|
||||
* 从URL搜索参数中获取authToken
|
||||
*/
|
||||
export const getAuthTokenFromUrl = (): string | null => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get('authToken');
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存authToken到localStorage
|
||||
*/
|
||||
export const saveAuthToken = (token: string): void => {
|
||||
localStorage.setItem(AUTH_TOKEN_KEY, token);
|
||||
};
|
||||
|
||||
/**
|
||||
* 从localStorage获取authToken
|
||||
*/
|
||||
export const getAuthToken = (): string | null => {
|
||||
return localStorage.getItem(AUTH_TOKEN_KEY);
|
||||
};
|
||||
|
||||
/**
|
||||
* 清除authToken
|
||||
*/
|
||||
export const clearAuthToken = (): void => {
|
||||
localStorage.removeItem(AUTH_TOKEN_KEY);
|
||||
};
|
||||
|
||||
/**
|
||||
* 检查并处理URL中的authToken
|
||||
* 如果URL中有authToken参数,则保存到localStorage并从URL中移除
|
||||
*/
|
||||
export const handleAuthTokenFromUrl = (): void => {
|
||||
const tokenFromUrl = getAuthTokenFromUrl();
|
||||
if (tokenFromUrl) {
|
||||
saveAuthToken(tokenFromUrl);
|
||||
|
||||
// 从URL中移除authToken参数
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete('authToken');
|
||||
window.history.replaceState({}, '', url.toString());
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user