14 KiB
14 KiB
用户管理API文档
概述
本文档描述了LingAdmin用户管理系统的API接口,包括用户注册、登录、认证和管理功能。
基础信息
- 基础URL:
http://localhost:5000/api - 内容类型:
application/json - 字符编码:
UTF-8
认证相关API
1. 用户注册
注册新用户账号。
端点: POST /auth/register
请求体:
{
"name": "张三",
"email": "zhangsan@example.com",
"password": "Password123!",
"role": "User" // 可选: "Admin", "User", "Editor"
}
成功响应 (201 Created):
{
"code": 200,
"message": "success",
"data": {
"id": 11,
"name": "张三",
"email": "zhangsan@example.com",
"role": "User",
"status": "Active",
"createdAt": "2026-01-28T09:30:00Z",
"lastLoginAt": null
}
}
错误响应 (400 Bad Request):
{
"code": 400,
"message": "User with this email already exists",
"data": null
}
2. 用户登录
用户登录并获取JWT令牌。
端点: POST /auth/login
请求体:
{
"email": "admin@example.com",
"password": "Admin123!"
}
成功响应 (200 OK):
{
"code": 200,
"message": "success",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"name": "Admin User",
"email": "admin@example.com",
"role": "Admin",
"status": "Active",
"createdAt": "2026-01-28T09:00:00Z",
"lastLoginAt": "2026-01-28T09:30:00Z"
}
}
}
错误响应 (401 Unauthorized):
{
"code": 401,
"message": "Invalid email or password",
"data": null
}
注意:
- 登录成功后返回的
token需要保存在客户端(localStorage或sessionStorage) - Token有效期为60分钟(可在appsettings.json中配置)
- 已有测试账号:
admin@example.com/Admin123!
3. 获取用户资料
获取指定用户的详细信息。
端点: GET /auth/profile/{id}
路径参数:
id(integer): 用户ID
成功响应 (200 OK):
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"name": "Admin User",
"email": "admin@example.com",
"role": "Admin",
"status": "Active",
"createdAt": "2026-01-28T09:00:00Z",
"lastLoginAt": "2026-01-28T09:30:00Z"
}
}
4. 修改密码
修改当前用户的密码。
端点: POST /auth/change-password/{id}
路径参数:
id(integer): 用户ID
请求体:
{
"currentPassword": "OldPassword123!",
"newPassword": "NewPassword123!"
}
成功响应 (200 OK):
{
"code": 200,
"message": "success",
"data": {
"message": "Password changed successfully"
}
}
错误响应 (400 Bad Request):
{
"code": 400,
"message": "Current password is incorrect",
"data": null
}
用户管理API
5. 获取用户列表
获取所有用户列表(管理员功能)。
端点: GET /users
成功响应 (200 OK):
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "Admin User",
"email": "admin@example.com",
"role": "Admin",
"status": "Active",
"createdAt": "2026-01-28T09:00:00Z",
"lastLoginAt": "2026-01-28T09:30:00Z"
},
{
"id": 2,
"name": "测试用户",
"email": "test@example.com",
"role": "User",
"status": "Active",
"createdAt": "2026-01-28T10:00:00Z",
"lastLoginAt": null
}
]
}
6. 获取单个用户
获取指定用户的详细信息。
端点: GET /users/{id}
路径参数:
id(integer): 用户ID
成功响应 (200 OK):
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"name": "Admin User",
"email": "admin@example.com",
"role": "Admin",
"status": "Active",
"createdAt": "2026-01-28T09:00:00Z",
"lastLoginAt": "2026-01-28T09:30:00Z"
}
}
7. 更新用户信息
更新用户的基本信息(部分更新)。
端点: PUT /users/{id}
路径参数:
id(integer): 用户ID
请求体 (所有字段可选):
{
"name": "新名称",
"email": "newemail@example.com",
"role": "Editor",
"status": "Inactive"
}
成功响应 (200 OK):
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"name": "新名称",
"email": "newemail@example.com",
"role": "Editor",
"status": "Inactive",
"createdAt": "2026-01-28T09:00:00Z",
"lastLoginAt": "2026-01-28T09:30:00Z"
}
}
注意:
- 只需提供要更新的字段
- 邮箱更新时会检查是否已被其他用户使用
8. 删除用户
删除指定用户。
端点: DELETE /users/{id}
路径参数:
id(integer): 用户ID
成功响应 (200 OK):
{
"code": 200,
"message": "success",
"data": {
"message": "User deleted successfully"
}
}
数据模型
User (用户)
interface User {
id: number; // 用户ID
name: string; // 用户名称
email: string; // 邮箱地址
role: string; // 角色: "Admin" | "User" | "Editor"
status: string; // 状态: "Active" | "Inactive"
createdAt: string; // 创建时间 (ISO 8601格式)
lastLoginAt: string | null; // 最后登录时间
}
ApiResponse (统一响应格式)
interface ApiResponse<T> {
code: number; // 状态码: 200=成功, 400=客户端错误, 401=未授权, 404=未找到, 500=服务器错误
message: string; // 响应消息
data: T | null; // 响应数据
}
前端集成示例
React + TypeScript 示例
1. 创建API服务
// src/services/api.ts
import axios from 'axios';
const API_BASE_URL = 'http://localhost:5000/api';
// 创建axios实例
export const apiClient = axios.create({
baseURL: API_BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});
// 请求拦截器 - 添加token
apiClient.interceptors.request.use(
(config) => {
const token = localStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// 响应拦截器 - 处理错误
apiClient.interceptors.response.use(
(response) => response.data,
(error) => {
if (error.response?.status === 401) {
// 处理未授权 - 清除token并跳转到登录页
localStorage.removeItem('authToken');
window.location.href = '/login';
}
return Promise.reject(error.response?.data || error);
}
);
2. 创建认证服务
// src/services/auth.service.ts
import { apiClient } from './api';
interface LoginRequest {
email: string;
password: string;
}
interface RegisterRequest {
name: string;
email: string;
password: string;
role?: string;
}
interface LoginResponse {
token: string;
user: User;
}
export const authService = {
// 登录
async login(credentials: LoginRequest): Promise<LoginResponse> {
const response = await apiClient.post('/auth/login', credentials);
if (response.code === 200) {
localStorage.setItem('authToken', response.data.token);
localStorage.setItem('currentUser', JSON.stringify(response.data.user));
}
return response.data;
},
// 注册
async register(userData: RegisterRequest): Promise<User> {
const response = await apiClient.post('/auth/register', userData);
return response.data;
},
// 登出
logout() {
localStorage.removeItem('authToken');
localStorage.removeItem('currentUser');
},
// 获取当前用户
getCurrentUser(): User | null {
const userStr = localStorage.getItem('currentUser');
return userStr ? JSON.parse(userStr) : null;
},
// 修改密码
async changePassword(userId: number, passwords: { currentPassword: string; newPassword: string }) {
const response = await apiClient.post(`/auth/change-password/${userId}`, passwords);
return response.data;
},
};
3. 创建用户服务
// src/services/user.service.ts
import { apiClient } from './api';
interface UpdateUserRequest {
name?: string;
email?: string;
role?: string;
status?: string;
}
export const userService = {
// 获取所有用户
async getAllUsers(): Promise<User[]> {
const response = await apiClient.get('/users');
return response.data;
},
// 获取单个用户
async getUserById(id: number): Promise<User> {
const response = await apiClient.get(`/users/${id}`);
return response.data;
},
// 更新用户
async updateUser(id: number, userData: UpdateUserRequest): Promise<User> {
const response = await apiClient.put(`/users/${id}`, userData);
return response.data;
},
// 删除用户
async deleteUser(id: number): Promise<void> {
await apiClient.delete(`/users/${id}`);
},
};
4. 登录组件示例
// src/components/Login.tsx
import React, { useState } from 'react';
import { authService } from '../services/auth.service';
export const Login: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
setLoading(true);
try {
const response = await authService.login({ email, password });
console.log('登录成功:', response.user);
// 跳转到主页
window.location.href = '/dashboard';
} catch (err: any) {
setError(err.message || '登录失败,请检查邮箱和密码');
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleLogin}>
<div>
<label>邮箱</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div>
<label>密码</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>
{error && <div className="error">{error}</div>}
<button type="submit" disabled={loading}>
{loading ? '登录中...' : '登录'}
</button>
</form>
);
};
5. 用户列表组件示例
// src/components/UserList.tsx
import React, { useEffect, useState } from 'react';
import { userService } from '../services/user.service';
export const UserList: React.FC = () => {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
loadUsers();
}, []);
const loadUsers = async () => {
try {
const data = await userService.getAllUsers();
setUsers(data);
} catch (error) {
console.error('加载用户失败:', error);
} finally {
setLoading(false);
}
};
const handleDelete = async (id: number) => {
if (confirm('确定要删除此用户吗?')) {
try {
await userService.deleteUser(id);
setUsers(users.filter(u => u.id !== id));
} catch (error) {
console.error('删除失败:', error);
}
}
};
if (loading) return <div>加载中...</div>;
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>邮箱</th>
<th>角色</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{users.map((user) => (
<tr key={user.id}>
<td>{user.id}</td>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.role}</td>
<td>{user.status}</td>
<td>
<button onClick={() => handleDelete(user.id)}>删除</button>
</td>
</tr>
))}
</tbody>
</table>
);
};
错误处理
常见状态码
| 状态码 | 说明 | 处理建议 |
|---|---|---|
| 200 | 成功 | 正常处理响应数据 |
| 400 | 请求参数错误 | 检查请求参数格式 |
| 401 | 未授权 | 清除token,跳转到登录页 |
| 404 | 资源未找到 | 提示用户资源不存在 |
| 500 | 服务器错误 | 提示用户稍后重试 |
错误处理示例
try {
const user = await userService.getUserById(id);
// 处理成功
} catch (error: any) {
if (error.code === 404) {
console.error('用户不存在');
} else if (error.code === 401) {
console.error('未授权,请重新登录');
authService.logout();
navigate('/login');
} else {
console.error('操作失败:', error.message);
}
}
安全注意事项
- Token存储: 建议使用
httpOnlyCookie或sessionStorage,避免XSS攻击 - HTTPS: 生产环境必须使用HTTPS协议
- 密码强度: 前端应验证密码强度(至少8位,包含大小写字母和数字)
- 输入验证: 前端和后端都应进行输入验证
- 错误信息: 避免在错误消息中泄露敏感信息
测试账号
系统提供以下测试账号用于开发测试:
| 邮箱 | 密码 | 角色 | 说明 |
|---|---|---|---|
| admin@example.com | Admin123! | Admin | 管理员账号(需要先注册创建) |
注意: 测试环境中的种子数据密码哈希存在问题,建议使用注册接口创建新用户进行测试。
更新日志
v1.0.0 (2026-01-28)
- ✅ 实现用户注册功能
- ✅ 实现用户登录与JWT认证
- ✅ 实现用户信息CRUD操作
- ✅ 实现密码修改功能
- ✅ 集成Dapr事件发布
- ✅ 添加密码安全哈希(PBKDF2)
技术支持
如有问题,请联系开发团队或查看以下资源:
- API测试脚本:
test-auth.ps1 - 数据库迁移:
Migrations/ - Swagger文档:
http://localhost:5000/swagger(开发环境)
附录
Dapr事件
系统会通过Dapr发布以下事件:
user-created: 用户注册成功user-login: 用户登录成功user-updated: 用户信息更新user-deleted: 用户被删除user-password-changed: 密码修改成功
前端可以订阅这些事件进行实时更新。