# 前端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 { return http.get('/token/user-info') }, /** * 获取用户名 * Token会自动从请求头中获取 */ getUsername(): Promise { return http.get('/token/username') }, /** * 验证Token * Token会自动从请求头中获取 */ validateToken(): Promise { return http.get('/token/validate') } } ``` ## 🎯 推荐使用AuthController接口 实际上,建议前端继续使用AuthController中的接口,因为它们提供了更完整的功能: ```typescript // services/auth.ts import { http } from '@/utils/request' export const authApi = { /** * 获取当前用户信息 * 推荐使用这个接口而不是 /token/user-info */ getUserInfo(): Promise { return http.get('/auth/user/info') }, /** * 获取用户名 * 推荐使用这个接口而不是 /token/username */ getUsername(): Promise { return http.get('/auth/username') }, /** * 验证Token * 推荐使用这个接口而不是 /token/validate */ validateToken(): Promise { 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错误 这次优化使后端接口更加标准化和安全,为将来的扩展打下了良好的基础!