Files
2025-10-27 23:57:31 +08:00

224 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 管理员登录认证系统设计文档
## 概述
本系统实现了普通用户和管理员用户的双重登录认证机制,两者相互独立,互不影响。
## 系统架构
### 用户类型区分
系统通过JWT Token中的`userType`字段区分用户类型:
- `user`: 普通用户
- `admin`: 管理员用户
### 核心组件
1. **JwtUtil** - JWT工具类
- 支持生成带用户类型的Token
- 支持从Token中提取用户类型
2. **AdminAuthService** - 管理员认证服务
- 管理员登录(账号+密码)
- Token生成和验证
- 登录信息记录
3. **AdminAuthInterceptor** - 管理员拦截器
- 拦截所有`/admin/**`路径
- 验证Token的有效性
- 验证用户类型为admin
4. **JwtAuthInterceptor** - 普通用户拦截器
- 拦截除管理员路径外的所有请求
- 验证普通用户Token
## API接口
### 管理员登录
```
POST /api/admin/auth/login
Content-Type: application/json
{
"account": "admin",
"password": "admin123"
}
响应:
{
"code": 200,
"message": "登录成功",
"data": {
"accessToken": "eyJhbGc...",
"refreshToken": "eyJhbGc...",
"expiresIn": 86400,
"adminInfo": {
"id": "xxx",
"account": "admin",
"username": "系统管理员",
"role": "super_admin",
...
},
"loginTime": "2025-10-27 10:00:00"
}
}
```
### 获取管理员信息
```
GET /api/admin/auth/info
Authorization: Bearer {accessToken}
响应:
{
"code": 200,
"message": "操作成功",
"data": {
"id": "xxx",
"account": "admin",
"username": "系统管理员",
"role": "super_admin",
...
}
}
```
### 管理员登出
```
POST /api/admin/auth/logout
Authorization: Bearer {accessToken}
响应:
{
"code": 200,
"message": "登出成功",
"data": null
}
```
### 刷新Token
```
POST /api/admin/auth/refreshToken
Content-Type: application/json
{
"refreshToken": "eyJhbGc..."
}
响应:
{
"code": 200,
"message": "令牌刷新成功",
"data": {
"accessToken": "eyJhbGc...",
"refreshToken": "eyJhbGc...",
"expiresIn": 86400,
...
}
}
```
## 默认管理员账号
系统初始化时会创建一个默认的超级管理员账号:
- **账号**: admin
- **密码**: admin123
- **角色**: super_admin
- **邮箱**: admin@emotion-museum.com
- **手机**: 13800138000
**重要提示**: 生产环境部署后请立即修改默认密码!
## 拦截器配置
### 管理员拦截器
- **拦截路径**: `/admin/**`
- **排除路径**:
- `/admin/auth/login` - 登录接口
- `/admin/auth/refreshToken` - 刷新Token接口
- **优先级**: 1(最高)
### 普通用户拦截器
- **拦截路径**: `/**`
- **排除路径**:
- `/auth/**` - 用户认证相关
- `/admin/**` - 管理员路径(由管理员拦截器处理)
- `/health` - 健康检查
- `/ws/**` - WebSocket
- `/swagger-ui/**` - API文档
- **优先级**: 2
## Token存储
### Redis存储
- **管理员AccessToken**: `admin_token:{adminId}` (24小时)
- **管理员RefreshToken**: `admin_refresh_token:{adminId}` (7天)
- **普通用户Token**: `token:{userId}` (24小时)
- **普通用户RefreshToken**: `refresh_token:{userId}` (7天)
## 安全特性
1. **密码加密**: 使用BCrypt算法加密存储
2. **Token隔离**: 管理员和普通用户Token完全隔离
3. **权限验证**: 管理员接口强制验证userType
4. **登录记录**: 记录最后登录时间、IP和登录次数
5. **状态检查**: 登录时检查账号状态
## 使用示例
### 前端调用示例
```javascript
// 管理员登录
async function adminLogin(account, password) {
const response = await fetch('/api/admin/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ account, password })
});
const result = await response.json();
if (result.code === 200) {
// 保存Token
localStorage.setItem('adminToken', result.data.accessToken);
localStorage.setItem('adminRefreshToken', result.data.refreshToken);
return result.data;
}
throw new Error(result.message);
}
// 调用管理员接口
async function callAdminApi(url, options = {}) {
const token = localStorage.getItem('adminToken');
const response = await fetch(url, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${token}`
}
});
return await response.json();
}
```
## 注意事项
1. **不要混用Token**: 管理员Token只能访问管理员接口,普通用户Token只能访问用户接口
2. **及时刷新Token**: Token过期前使用refreshToken刷新
3. **安全存储**: 前端应安全存储Token,避免XSS攻击
4. **HTTPS**: 生产环境必须使用HTTPS传输
5. **修改默认密码**: 部署后立即修改默认管理员密码
## 扩展功能
后续可以扩展的功能:
- 管理员角色权限细分
- 操作日志记录
- 多因素认证(MFA
- IP白名单限制
- 登录失败次数限制