代码优化

This commit is contained in:
2025-10-13 10:43:08 +08:00
parent b6818b179c
commit bc3ed2d872
40 changed files with 3189 additions and 788 deletions
+307
View File
@@ -0,0 +1,307 @@
# 前端Token API迁移指南
## 📋 概述
TokenController接口已经从POST请求体传递token的方式优化为GET请求头传递token的标准方式。如果前端需要使用这些接口,请参考以下迁移指南。
## ✅ 当前状态
经过检查,前端代码中**没有直接使用**以下接口:
- `/token/user-info`
- `/token/username`
- `/token/validate`
前端主要使用的是AuthController中的接口:
- `/auth/user/info` - 获取用户信息
- `/auth/username` - 获取用户名
- `/auth/validateToken` - 验证Token
因此,**本次优化不需要修改前端代码**。
## 📚 接口使用指南(如果将来需要)
### 1. 获取用户信息
#### 旧方式(已废弃)
```typescript
// ❌ 不推荐:POST请求,token在请求体中
const response = await http.post('/token/user-info', {
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
})
```
#### 新方式(推荐)
```typescript
// ✅ 推荐:GET请求,token在请求头中(自动添加)
const response = await http.get('/token/user-info')
// 或者手动指定token(特殊场景)
const response = await http.get('/token/user-info', {
headers: {
'Authorization': `Bearer ${token}`
}
})
```
### 2. 获取用户名
#### 旧方式(已废弃)
```typescript
// ❌ 不推荐
const response = await http.post('/token/username', {
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
})
```
#### 新方式(推荐)
```typescript
// ✅ 推荐
const response = await http.get('/token/username')
```
### 3. 验证Token
#### 旧方式(已废弃)
```typescript
// ❌ 不推荐
const response = await http.post('/token/validate', {
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
})
```
#### 新方式(推荐)
```typescript
// ✅ 推荐
const response = await http.get('/token/validate')
```
## 🔧 HTTP请求工具配置
### 确保请求拦截器自动添加Token
大多数项目的HTTP工具已经配置了自动添加Authorization请求头的拦截器:
```typescript
// utils/request.ts 或 utils/http.ts
import axios from 'axios'
const http = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 10000
})
// 请求拦截器:自动添加Token
http.interceptors.request.use(
(config) => {
// 从localStorage获取token
const token = localStorage.getItem('access_token')
// 如果token存在,添加到请求头
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
return Promise.reject(error)
}
)
export { http }
```
### 如果项目还没有配置,请添加以下代码
```typescript
// 1. 在请求拦截器中添加token
http.interceptors.request.use((config) => {
const token = localStorage.getItem('access_token')
if (token && !config.headers.Authorization) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
// 2. 在响应拦截器中处理401错误
http.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
// Token过期或无效,跳转到登录页
localStorage.removeItem('access_token')
window.location.href = '/login'
}
return Promise.reject(error)
}
)
```
## 📝 API服务封装示例
如果需要使用TokenController的接口,可以创建以下服务:
```typescript
// services/token.ts
import { http } from '@/utils/request'
import type { UserInfo } from '@/types'
export const tokenApi = {
/**
* 获取用户信息
* Token会自动从请求头中获取
*/
getUserInfo(): Promise<UserInfo> {
return http.get('/token/user-info')
},
/**
* 获取用户名
* Token会自动从请求头中获取
*/
getUsername(): Promise<string> {
return http.get('/token/username')
},
/**
* 验证Token
* Token会自动从请求头中获取
*/
validateToken(): Promise<string> {
return http.get('/token/validate')
}
}
```
## 🎯 推荐使用AuthController接口
实际上,建议前端继续使用AuthController中的接口,因为它们提供了更完整的功能:
```typescript
// services/auth.ts
import { http } from '@/utils/request'
export const authApi = {
/**
* 获取当前用户信息
* 推荐使用这个接口而不是 /token/user-info
*/
getUserInfo(): Promise<UserInfo> {
return http.get('/auth/user/info')
},
/**
* 获取用户名
* 推荐使用这个接口而不是 /token/username
*/
getUsername(): Promise<string> {
return http.get('/auth/username')
},
/**
* 验证Token
* 推荐使用这个接口而不是 /token/validate
*/
validateToken(): Promise<boolean> {
return http.get('/auth/validateToken')
}
}
```
## 🔍 接口对比
| 功能 | TokenController | AuthController | 推荐使用 |
|------|----------------|----------------|---------|
| 获取用户信息 | `GET /token/user-info` | `GET /auth/user/info` | AuthController |
| 获取用户名 | `GET /token/username` | `GET /auth/username` | AuthController |
| 验证Token | `GET /token/validate` | `GET /auth/validateToken` | AuthController |
**推荐理由**
- AuthController接口功能更完整
- 已经在项目中广泛使用
- 有更好的错误处理和日志记录
- 与认证流程集成更紧密
## ⚠️ 注意事项
### 1. Token存储位置
确保token存储在正确的位置:
```typescript
// 登录成功后存储token
localStorage.setItem('access_token', response.accessToken)
// 登出时清除token
localStorage.removeItem('access_token')
```
### 2. Token格式
确保token以正确的格式发送:
```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
### 3. 错误处理
处理token相关的错误:
```typescript
try {
const userInfo = await tokenApi.getUserInfo()
} catch (error) {
if (error.response?.status === 401) {
// Token无效或过期
console.error('Token无效,请重新登录')
// 跳转到登录页
router.push('/login')
}
}
```
### 4. Token刷新
实现token自动刷新机制:
```typescript
http.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true
try {
// 尝试刷新token
const refreshToken = localStorage.getItem('refresh_token')
const response = await authApi.refreshToken({ refreshToken })
// 更新token
localStorage.setItem('access_token', response.accessToken)
// 重试原始请求
originalRequest.headers.Authorization = `Bearer ${response.accessToken}`
return http(originalRequest)
} catch (refreshError) {
// 刷新失败,跳转到登录页
localStorage.clear()
window.location.href = '/login'
return Promise.reject(refreshError)
}
}
return Promise.reject(error)
}
)
```
## ✅ 总结
1. **当前状态**:前端代码不需要修改,因为没有使用TokenController接口
2. **推荐做法**:继续使用AuthController接口
3. **如果需要使用TokenController**
- 使用GET方法
- Token在请求头中自动传递
- 确保HTTP工具配置了请求拦截器
4. **最佳实践**
- Token存储在localStorage
- 使用Bearer格式
- 实现自动刷新机制
- 处理401错误
这次优化使后端接口更加标准化和安全,为将来的扩展打下了良好的基础!