334 lines
7.4 KiB
Markdown
334 lines
7.4 KiB
Markdown
# 用户认证系统
|
||
|
||
## 概述
|
||
|
||
用户认证系统提供完整的用户注册、登录、密码管理功能,支持传统用户名密码登录和第三方OAuth登录。
|
||
|
||
## 功能特性
|
||
|
||
- 🔐 多种登录方式:用户名/邮箱/手机号登录
|
||
- 📝 用户注册和信息管理
|
||
- 🐙 GitHub OAuth 第三方登录
|
||
- 🔄 密码重置和修改
|
||
- 🛡️ bcrypt 密码加密
|
||
- 🎯 基于角色的权限控制
|
||
|
||
## 架构设计
|
||
|
||
### 分层结构
|
||
|
||
```
|
||
src/
|
||
├── business/login/ # 业务逻辑层
|
||
│ ├── login.controller.ts # HTTP 控制器
|
||
│ ├── login.service.ts # 业务服务
|
||
│ ├── login.dto.ts # 数据传输对象
|
||
│ ├── login.service.spec.ts # 业务服务测试
|
||
│ └── login.module.ts # 业务模块
|
||
├── core/
|
||
│ ├── login_core/ # 核心功能层
|
||
│ │ ├── login_core.service.ts # 核心认证逻辑
|
||
│ │ ├── login_core.service.spec.ts # 核心服务测试
|
||
│ │ └── login_core.module.ts # 核心模块
|
||
│ └── db/users/ # 数据访问层
|
||
│ ├── users.entity.ts # 用户实体
|
||
│ ├── users.service.ts # 用户数据服务
|
||
│ └── users.dto.ts # 用户 DTO
|
||
```
|
||
|
||
### 职责分离
|
||
|
||
#### 1. 业务逻辑层 (Business Layer)
|
||
- **位置**: `src/business/login/`
|
||
- **职责**:
|
||
- 处理HTTP请求和响应
|
||
- 数据格式化和验证
|
||
- 业务流程控制
|
||
- 错误处理和日志记录
|
||
|
||
#### 2. 核心功能层 (Core Layer)
|
||
- **位置**: `src/core/login_core/`
|
||
- **职责**:
|
||
- 认证核心算法实现
|
||
- 密码加密和验证
|
||
- 用户查找和匹配
|
||
- 令牌生成和验证
|
||
|
||
#### 3. 数据访问层 (Data Access Layer)
|
||
- **位置**: `src/core/db/users/`
|
||
- **职责**:
|
||
- 数据库操作封装
|
||
- 实体关系映射
|
||
- 数据完整性保证
|
||
- 查询优化
|
||
|
||
## API 接口
|
||
|
||
### 用户注册
|
||
|
||
```bash
|
||
POST /auth/register
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"username": "testuser",
|
||
"password": "password123",
|
||
"nickname": "测试用户",
|
||
"email": "test@example.com",
|
||
"phone": "+8613800138000"
|
||
}
|
||
```
|
||
|
||
**响应**:
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"user": {
|
||
"id": "1",
|
||
"username": "testuser",
|
||
"nickname": "测试用户",
|
||
"email": "test@example.com",
|
||
"phone": "+8613800138000",
|
||
"avatar_url": null,
|
||
"role": 1,
|
||
"created_at": "2025-12-17T10:00:00.000Z"
|
||
},
|
||
"access_token": "eyJ1c2VySWQiOiIxIiwidXNlcm5hbWUiOiJ0ZXN0dXNlciJ9...",
|
||
"is_new_user": true,
|
||
"message": "注册成功"
|
||
},
|
||
"message": "注册成功"
|
||
}
|
||
```
|
||
|
||
### 用户登录
|
||
|
||
```bash
|
||
POST /auth/login
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"identifier": "testuser", # 支持用户名/邮箱/手机号
|
||
"password": "password123"
|
||
}
|
||
```
|
||
|
||
### GitHub OAuth登录
|
||
|
||
```bash
|
||
POST /auth/github
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"github_id": "12345678",
|
||
"username": "githubuser",
|
||
"nickname": "GitHub用户",
|
||
"email": "github@example.com",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/12345678"
|
||
}
|
||
```
|
||
|
||
### 密码重置
|
||
|
||
```bash
|
||
# 1. 发送验证码
|
||
POST /auth/forgot-password
|
||
{
|
||
"identifier": "test@example.com"
|
||
}
|
||
|
||
# 2. 重置密码
|
||
POST /auth/reset-password
|
||
{
|
||
"identifier": "test@example.com",
|
||
"verification_code": "123456",
|
||
"new_password": "newpassword123"
|
||
}
|
||
```
|
||
|
||
### 修改密码
|
||
|
||
```bash
|
||
PUT /auth/change-password
|
||
{
|
||
"user_id": "1",
|
||
"old_password": "password123",
|
||
"new_password": "newpassword123"
|
||
}
|
||
```
|
||
|
||
## 数据模型
|
||
|
||
### 用户实体 (Users Entity)
|
||
|
||
```typescript
|
||
{
|
||
id: bigint, // 主键ID
|
||
username: string, // 用户名(唯一)
|
||
email?: string, // 邮箱(唯一,可选)
|
||
phone?: string, // 手机号(唯一,可选)
|
||
password_hash?: string, // 密码哈希(OAuth用户为空)
|
||
nickname: string, // 显示昵称
|
||
github_id?: string, // GitHub ID(唯一,可选)
|
||
avatar_url?: string, // 头像URL
|
||
role: number, // 用户角色(1-普通,9-管理员)
|
||
created_at: Date, // 创建时间
|
||
updated_at: Date // 更新时间
|
||
}
|
||
```
|
||
|
||
### 数据库设计特点
|
||
|
||
1. **唯一性约束**: username, email, phone, github_id
|
||
2. **索引优化**: 主键、唯一索引、角色索引
|
||
3. **字符集支持**: utf8mb4,支持emoji
|
||
4. **数据类型**: BIGINT主键,VARCHAR字段,DATETIME时间戳
|
||
|
||
## 安全机制
|
||
|
||
### 1. 密码安全
|
||
- **加密算法**: bcrypt (saltRounds=12)
|
||
- **强度验证**: 最少8位,包含字母和数字
|
||
- **存储安全**: 只存储哈希值,不存储明文
|
||
|
||
### 2. 数据验证
|
||
- **输入验证**: class-validator装饰器
|
||
- **SQL注入防护**: TypeORM参数化查询
|
||
- **XSS防护**: 数据转义和验证
|
||
|
||
### 3. 访问控制
|
||
- **令牌机制**: 基于用户信息的访问令牌
|
||
- **角色权限**: 基于角色的访问控制(RBAC)
|
||
- **会话管理**: 令牌生成和验证
|
||
|
||
### 4. 错误处理
|
||
- **统一异常**: NestJS异常过滤器
|
||
- **日志记录**: 操作日志和错误日志
|
||
- **信息脱敏**: 敏感信息自动脱敏
|
||
|
||
## 测试覆盖
|
||
|
||
### 单元测试
|
||
- 核心服务测试:`src/core/login_core/login_core.service.spec.ts`
|
||
- 业务服务测试:`src/business/login/login.service.spec.ts`
|
||
|
||
### 集成测试
|
||
- 端到端测试:`test/business/login.e2e-spec.ts`
|
||
|
||
### 测试用例
|
||
- 用户注册和登录流程
|
||
- GitHub OAuth认证
|
||
- 密码重置和修改
|
||
- 数据验证和错误处理
|
||
- 安全性测试
|
||
|
||
## 使用示例
|
||
|
||
### JavaScript/TypeScript
|
||
|
||
```javascript
|
||
// 用户注册
|
||
const registerResponse = await fetch('/auth/register', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
username: 'testuser',
|
||
password: 'password123',
|
||
nickname: '测试用户',
|
||
email: 'test@example.com'
|
||
})
|
||
});
|
||
|
||
const registerData = await registerResponse.json();
|
||
console.log(registerData);
|
||
|
||
// 用户登录
|
||
const loginResponse = await fetch('/auth/login', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
identifier: 'testuser',
|
||
password: 'password123'
|
||
})
|
||
});
|
||
|
||
const loginData = await loginResponse.json();
|
||
console.log(loginData);
|
||
```
|
||
|
||
### curl 命令
|
||
|
||
```bash
|
||
# 用户注册
|
||
curl -X POST http://localhost:3000/auth/register \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"username": "testuser",
|
||
"password": "password123",
|
||
"nickname": "测试用户",
|
||
"email": "test@example.com"
|
||
}'
|
||
|
||
# 用户登录
|
||
curl -X POST http://localhost:3000/auth/login \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"identifier": "testuser",
|
||
"password": "password123"
|
||
}'
|
||
```
|
||
|
||
## 错误处理
|
||
|
||
### 常见错误代码
|
||
|
||
- `LOGIN_FAILED`: 登录失败
|
||
- `REGISTER_FAILED`: 注册失败
|
||
- `GITHUB_OAUTH_FAILED`: GitHub登录失败
|
||
- `SEND_CODE_FAILED`: 发送验证码失败
|
||
- `RESET_PASSWORD_FAILED`: 密码重置失败
|
||
- `CHANGE_PASSWORD_FAILED`: 密码修改失败
|
||
|
||
### 错误响应格式
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"message": "错误描述",
|
||
"error_code": "ERROR_CODE"
|
||
}
|
||
```
|
||
|
||
## 扩展功能
|
||
|
||
### 计划中的功能
|
||
|
||
1. **JWT令牌管理**
|
||
- 访问令牌和刷新令牌
|
||
- 令牌黑名单机制
|
||
- 自动刷新功能
|
||
|
||
2. **多因子认证**
|
||
- 短信验证码
|
||
- 邮箱验证码
|
||
- TOTP应用支持
|
||
|
||
3. **社交登录扩展**
|
||
- 微信登录
|
||
- QQ登录
|
||
- 微博登录
|
||
|
||
4. **安全增强**
|
||
- 登录失败次数限制
|
||
- IP白名单/黑名单
|
||
- 设备指纹识别
|
||
|
||
5. **用户管理**
|
||
- 用户状态管理(激活/禁用)
|
||
- 用户角色权限细化
|
||
- 用户行为日志记录 |