You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
11 KiB
11 KiB
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>
↓
后端验证 token
↓
后端返回数据
↓
axios 响应拦截器处理(提取 data)
↓
组件接收数据
💻 代码实现细节
axios 实例 (src/api/index.ts)
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
关键点:
- 所有请求自动添加
Authorization: Bearer <token> - 所有响应自动提取
response.data - 401 错误自动清除 token 并跳转
API 接口定义 (src/api/auth.ts)
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<LoginResponse> => {
return http.post('/auth/login', credentials)
}
使用方式:
const response = await loginApi({ username: 'admin', password: '123456' })
// response.code === 200
// response.data.token
// response.data.user
认证 Store (src/stores/auth.ts)
export const useAuthStore = defineStore('auth', () => {
const login = async (username: string, password: string): Promise<boolean> => {
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)
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
请求:
{
"username": "admin",
"password": "123456"
}
响应格式(必须严格按照):
{
"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 <token>中使用data.user必须包含至少id, username, email, role字段
📝 添加更多 API 接口
例子:用户列表 API
- 在
src/api/中创建users.ts:
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<UsersResponse> => {
return http.get('/users', {
params: { page, limit }
})
}
// 创建用户
export const createUserApi = (data: User): Promise<any> => {
return http.post('/users', data)
}
// 更新用户
export const updateUserApi = (id: number, data: Partial<User>): Promise<any> => {
return http.put(`/users/${id}`, data)
}
// 删除用户
export const deleteUserApi = (id: number): Promise<any> => {
return http.delete(`/users/${id}`)
}
- 在组件中使用:
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
在代码中使用
const baseURL = import.meta.env.VITE_API_URL
console.log(baseURL) // 自动根据环境选择
// 或直接在 axios 配置中
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api'
🧪 测试步骤
1. 启动后端服务
# Node.js Express 示例
node server.js
# 或 Python Flask 示例
python app.py
# 或你自己的后端服务
2. 验证后端在运行
访问 http://localhost:3000/api/auth/login (应该看到 404 或错误,说明服务在运行)
3. 使用 cURL 测试登录
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"123456"}'
应该返回:
{
"code": 200,
"message": "登录成功",
"data": {
"token": "...",
"user": {...}
}
}
4. 启动前端
npm run dev
5. 在前端登录
- 访问 http://localhost:5173
- 输入用户名和密码
- 点击登录
- 如果成功,应该跳转到仪表板
6. 检查浏览器开发者工具
- Network 标签: 查看请求和响应
- Application 标签: 查看 localStorage 中的
auth_token - Console 标签: 查看是否有错误
🔒 安全建议
- 始终使用 HTTPS (生产环境)
- 密码必须加密存储 (使用 bcrypt 等)
- 使用 JWT 令牌 而不是 session
- 设置合理的 token 过期时间 (如 7 天)
- 实现 token 刷新机制 (可选但推荐)
- 验证 CORS 配置 只允许特定域名
- 记录所有登录尝试 用于审计
- 使用速率限制 防止暴力破解
常见问题
Q: 如何在其他组件中获取当前用户?
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: 如何在请求中添加其他头信息?
// 在 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: 如何处理超时错误?
const login = async () => {
try {
await authStore.login(username, password)
} catch (error: any) {
if (error.code === 'ECONNABORTED') {
ElMessage.error('请求超时,请检查网络')
} else {
ElMessage.error(error.message)
}
}
}
Q: 前后端如何联调?
- 后端启动在 http://localhost:3000
- 前端启动在 http://localhost:5173
- 确保
.env.development中VITE_API_URL=http://localhost:3000/api - 后端需要配置 CORS 允许 http://localhost:5173 访问
Q: CORS 错误怎么解决?
后端需要配置 CORS:
Express 示例:
const cors = require('cors')
app.use(cors({
origin: 'http://localhost:5173',
credentials: true
}))
Flask 示例:
from flask_cors import CORS
CORS(app, resources={r"/api/*": {"origins": "http://localhost:5173"}})
📚 相关文档
- API 集成详细指南 - 完整的 API 使用说明
- 后端 API 实现参考 - Node.js/Python 后端示例代码
- 项目总结 - 整个项目的概览
🎉 总结
你现在有:
✅ 完整的 axios 配置(请求/响应拦截器) ✅ API 服务层架构 ✅ 登录示例(已与后端集成) ✅ 完整的类型定义 (TypeScript) ✅ 环境变量配置 ✅ 详细的文档和后端示例
下一步:
- 启动你的后端服务,确保监听 3000 端口
- 实现后端的
/api/auth/login接口,返回上述格式的 JSON - 运行
npm run dev启动前端 - 测试登录功能
有任何问题,请参考文档或查看相关代码注释!🚀