# API 集成完整指南 你好!现在项目已经完全配置好了 axios 和 API 层。以下是完整的说明。 ## 🎯 快速概览 ### 已为你完成的工作 ✅ **Axios 配置** - 完整的 HTTP 客户端配置 ✅ **API 服务层** - 登录 API 接口定义 ✅ **认证 Store** - 与后端 API 集成的状态管理 ✅ **登录页面** - 支持异步 API 调用 ✅ **环境配置** - 开发和生产环境变量 ✅ **详细文档** - API 集成指南和后端示例 ## 📁 项目结构 ``` src/ ├── api/ │ ├── index.ts ← axios 实例(请求/响应拦截器) │ └── auth.ts ← 登录 API 接口(可扩展) ├── stores/ │ └── auth.ts ← 认证状态(调用 API) ├── views/ │ └── LoginView.vue ← 登录页面(异步登录) └── ... root/ ├── .env.development ← 开发环境配置 ├── .env.production ← 生产环境配置 ├── API_INTEGRATION_GUIDE.md ← API 集成详细指南 ├── BACKEND_API_EXAMPLE.md ← 后端实现参考 └── ... ``` ## 🔄 工作流程 ### 1️⃣ 用户登录流程 ``` 用户输入用户名和密码 ↓ 点击"登录"按钮 ↓ LoginView.vue 调用 authStore.login(username, password) ↓ authStore 调用 loginApi({ username, password }) ↓ axios 发送 POST /api/auth/login 请求 ↓ axios 拦截器处理: - 添加 Authorization 头 - 处理错误响应 ↓ 后端返回 JSON 响应 ↓ 前端解析 response.data(自动由拦截器处理) ↓ 保存 token 和 user 到 localStorage ↓ 路由跳转到仪表板 ``` ### 2️⃣ 后续请求流程 ``` 任何组件需要调用 API ↓ 导入 API 函数(如 getUsersApi) ↓ await getUsersApi() ↓ axios 请求拦截器自动添加 Authorization: Bearer ↓ 后端验证 token ↓ 后端返回数据 ↓ axios 响应拦截器处理(提取 data) ↓ 组件接收数据 ``` ## 💻 代码实现细节 ### axios 实例 (`src/api/index.ts`) ```typescript import axios from 'axios' const instance = axios.create({ baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api', timeout: 10000 }) // 请求拦截器 - 自动添加 token instance.interceptors.request.use((config) => { const token = localStorage.getItem('auth_token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) // 响应拦截器 - 处理错误和 token 过期 instance.interceptors.response.use( (response) => response.data, // ← 返回 response.data (error) => { if (error.response?.status === 401) { // token 过期,清除并跳转 localStorage.removeItem('auth_token') window.location.href = '/login' } return Promise.reject(error) } ) export default instance ``` **关键点:** 1. 所有请求自动添加 `Authorization: Bearer ` 2. 所有响应自动提取 `response.data` 3. 401 错误自动清除 token 并跳转 ### API 接口定义 (`src/api/auth.ts`) ```typescript import http from './index' export interface LoginRequest { username: string password: string } export interface LoginResponse { code: number message: string data: { token: string user: User } } export const loginApi = (credentials: LoginRequest): Promise => { return http.post('/auth/login', credentials) } ``` **使用方式:** ```typescript const response = await loginApi({ username: 'admin', password: '123456' }) // response.code === 200 // response.data.token // response.data.user ``` ### 认证 Store (`src/stores/auth.ts`) ```typescript export const useAuthStore = defineStore('auth', () => { const login = async (username: string, password: string): Promise => { try { const response = await loginApi({ username, password }) if (response.code === 200 && response.data) { token.value = response.data.token user.value = response.data.user localStorage.setItem('auth_token', token.value) return true } } catch (error) { console.error('登录失败:', error) return false } } return { login, logout, user, token, isAuthenticated } }) ``` ### 登录页面 (`src/views/LoginView.vue`) ```typescript const handleLogin = async () => { loading.value = true try { // 调用异步登录 const success = await authStore.login(username.value, password.value) if (success) { ElMessage.success('登录成功') router.push('/admin/dashboard') } else { ElMessage.error('登录失败') } } catch (error: any) { ElMessage.error(error?.message || '登录出错') } finally { loading.value = false } } ``` ## 🛠 后端 API 需要返回什么? ### 登录接口 **端点:** `POST /api/auth/login` **请求:** ```json { "username": "admin", "password": "123456" } ``` **响应格式(必须严格按照):** ```json { "code": 200, "message": "登录成功", "data": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": "1", "username": "admin", "email": "admin@example.com", "role": "admin" } } } ``` **关键点:** - `code` 必须是 200 表示成功 - `data.token` 是 JWT token,后续请求在 `Authorization: Bearer ` 中使用 - `data.user` 必须包含至少 `id, username, email, role` 字段 ## 📝 添加更多 API 接口 ### 例子:用户列表 API 1. **在 `src/api/` 中创建 `users.ts`:** ```typescript import http from './index' export interface User { id: number username: string email: string role: string } export interface UsersResponse { code: number message: string data: { items: User[] total: number } } // 获取用户列表 export const getUsersApi = ( page: number = 1, limit: number = 10 ): Promise => { return http.get('/users', { params: { page, limit } }) } // 创建用户 export const createUserApi = (data: User): Promise => { return http.post('/users', data) } // 更新用户 export const updateUserApi = (id: number, data: Partial): Promise => { return http.put(`/users/${id}`, data) } // 删除用户 export const deleteUserApi = (id: number): Promise => { return http.delete(`/users/${id}`) } ``` 2. **在组件中使用:** ```typescript import { getUsersApi } from '@/api/users' const users = ref([]) const loading = ref(false) const fetchUsers = async () => { loading.value = true try { const response = await getUsersApi(1, 10) if (response.code === 200) { users.value = response.data.items } } catch (error) { ElMessage.error('获取用户列表失败') } finally { loading.value = false } } onMounted(() => { fetchUsers() }) ``` ## 🌐 环境配置 ### 开发环境 (`.env.development`) ``` VITE_API_URL=http://localhost:3000/api ``` ### 生产环境 (`.env.production`) ``` VITE_API_URL=https://api.example.com/api ``` ### 在代码中使用 ```typescript const baseURL = import.meta.env.VITE_API_URL console.log(baseURL) // 自动根据环境选择 // 或直接在 axios 配置中 baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api' ``` ## 🧪 测试步骤 ### 1. 启动后端服务 ```bash # Node.js Express 示例 node server.js # 或 Python Flask 示例 python app.py # 或你自己的后端服务 ``` ### 2. 验证后端在运行 访问 `http://localhost:3000/api/auth/login` (应该看到 404 或错误,说明服务在运行) ### 3. 使用 cURL 测试登录 ```bash curl -X POST http://localhost:3000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"123456"}' ``` 应该返回: ```json { "code": 200, "message": "登录成功", "data": { "token": "...", "user": {...} } } ``` ### 4. 启动前端 ```bash npm run dev ``` ### 5. 在前端登录 - 访问 http://localhost:5173 - 输入用户名和密码 - 点击登录 - 如果成功,应该跳转到仪表板 ### 6. 检查浏览器开发者工具 - **Network 标签:** 查看请求和响应 - **Application 标签:** 查看 localStorage 中的 `auth_token` - **Console 标签:** 查看是否有错误 ## 🔒 安全建议 1. **始终使用 HTTPS** (生产环境) 2. **密码必须加密存储** (使用 bcrypt 等) 3. **使用 JWT 令牌** 而不是 session 4. **设置合理的 token 过期时间** (如 7 天) 5. **实现 token 刷新机制** (可选但推荐) 6. **验证 CORS 配置** 只允许特定域名 7. **记录所有登录尝试** 用于审计 8. **使用速率限制** 防止暴力破解 ## 常见问题 ### Q: 如何在其他组件中获取当前用户? ```typescript import { useAuthStore } from '@/stores/auth' const authStore = useAuthStore() console.log(authStore.user) // 当前用户 console.log(authStore.token) // 当前 token ``` ### Q: 如何处理 token 刷新? 参考 `src/api/auth.ts` 中已定义的 `refreshTokenApi` 函数,在响应拦截器中实现 token 刷新逻辑。 ### Q: 如何在请求中添加其他头信息? ```typescript // 在 src/api/index.ts 中修改请求拦截器 instance.interceptors.request.use((config) => { const token = localStorage.getItem('auth_token') if (token) { config.headers.Authorization = `Bearer ${token}` } // 添加其他头 config.headers['X-Custom-Header'] = 'value' return config }) ``` ### Q: 如何处理超时错误? ```typescript const login = async () => { try { await authStore.login(username, password) } catch (error: any) { if (error.code === 'ECONNABORTED') { ElMessage.error('请求超时,请检查网络') } else { ElMessage.error(error.message) } } } ``` ### Q: 前后端如何联调? 1. 后端启动在 http://localhost:3000 2. 前端启动在 http://localhost:5173 3. 确保 `.env.development` 中 `VITE_API_URL=http://localhost:3000/api` 4. 后端需要配置 CORS 允许 http://localhost:5173 访问 ### Q: CORS 错误怎么解决? 后端需要配置 CORS: **Express 示例:** ```javascript const cors = require('cors') app.use(cors({ origin: 'http://localhost:5173', credentials: true })) ``` **Flask 示例:** ```python from flask_cors import CORS CORS(app, resources={r"/api/*": {"origins": "http://localhost:5173"}}) ``` ## 📚 相关文档 - [API 集成详细指南](./API_INTEGRATION_GUIDE.md) - 完整的 API 使用说明 - [后端 API 实现参考](./BACKEND_API_EXAMPLE.md) - Node.js/Python 后端示例代码 - [项目总结](./PROJECT_SUMMARY.md) - 整个项目的概览 ## 🎉 总结 你现在有: ✅ 完整的 axios 配置(请求/响应拦截器) ✅ API 服务层架构 ✅ 登录示例(已与后端集成) ✅ 完整的类型定义 (TypeScript) ✅ 环境变量配置 ✅ 详细的文档和后端示例 **下一步:** 1. 启动你的后端服务,确保监听 3000 端口 2. 实现后端的 `/api/auth/login` 接口,返回上述格式的 JSON 3. 运行 `npm run dev` 启动前端 4. 测试登录功能 有任何问题,请参考文档或查看相关代码注释!🚀