Files
schoolNews/schoolNewsServ/auth/注册功能说明.md

431 lines
10 KiB
Markdown
Raw 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.

# 注册功能说明文档
## 功能概述
系统支持三种注册方式:
1. **用户名注册** - 直接使用用户名+密码注册
2. **手机号注册** - 使用手机号+验证码+密码注册
3. **邮箱注册** - 使用邮箱+验证码+密码注册
## API接口
### 接口地址
```
POST /auth/register
```
### 请求参数
#### 通用参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| registerType | String | 是 | 注册类型username/phone/email |
| password | String | 是 | 密码至少6个字符 |
| confirmPassword | String | 是 | 确认密码 |
| studentId | String | 否 | 学号 |
#### 用户名注册 (registerType=username)
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| username | String | 是 | 用户名3-20字符仅字母数字下划线 |
#### 手机号注册 (registerType=phone)
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| phone | String | 是 | 手机号11位中国手机号 |
| smsCode | String | 是 | 手机验证码6位数字 |
#### 邮箱注册 (registerType=email)
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| email | String | 是 | 邮箱地址 |
| emailCode | String | 是 | 邮箱验证码6位数字 |
### 请求示例
#### 1. 用户名注册
```json
{
"registerType": "username",
"username": "zhangsan",
"password": "123456",
"confirmPassword": "123456",
"studentId": "2021001"
}
```
#### 2. 手机号注册
```json
{
"registerType": "phone",
"phone": "13800138000",
"smsCode": "123456",
"password": "123456",
"confirmPassword": "123456",
"studentId": "2021001"
}
```
#### 3. 邮箱注册
```json
{
"registerType": "email",
"email": "user@example.com",
"emailCode": "123456",
"password": "123456",
"confirmPassword": "123456",
"studentId": "2021001"
}
```
### 响应结果
#### 注册成功
```json
{
"code": 200,
"message": "注册成功",
"data": {
"user": {
"ID": "xxx",
"username": "zhangsan",
"email": "user@example.com",
"phone": "13800138000",
"status": 0
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"loginTime": "2025-11-03T10:30:00",
"ipAddress": "127.0.0.1"
}
}
```
#### 注册失败
```json
{
"code": 500,
"message": "用户已存在",
"data": null
}
```
## 业务流程
### 1. 用户名注册流程
```
用户输入用户名和密码
验证用户名格式3-20字符字母数字下划线
验证密码至少6字符两次输入一致
检查用户名是否已存在
密码加密BCrypt
创建用户账号
自动登录并返回token
```
### 2. 手机号注册流程
```
用户输入手机号
点击"获取验证码"按钮
系统发送短信验证码60秒限制
用户输入验证码和密码
验证手机号格式
验证验证码10分钟有效期
检查手机号是否已注册
密码加密BCrypt
创建用户账号(用户名=手机号)
删除验证码(防止重复使用)
自动登录并返回token
```
### 3. 邮箱注册流程
```
用户输入邮箱
点击"获取验证码"按钮
系统发送邮件验证码60秒限制
用户输入验证码和密码
验证邮箱格式
验证验证码10分钟有效期
检查邮箱是否已注册
密码加密BCrypt
创建用户账号(用户名=邮箱前缀)
删除验证码(防止重复使用)
自动登录并返回token
```
## 安全机制
### 1. 密码加密
- 使用 BCryptPasswordEncoder 进行密码加密
- 不可逆加密,安全性高
- 每次加密结果不同内置salt
### 2. 验证码机制
- **有效期**10分钟
- **发送频率**60秒只能发送一次
- **一次性使用**:验证后立即删除
- **存储位置**Redis
- 手机验证码:`sms:code:手机号`
- 邮箱验证码:`email:code:邮箱`
### 3. 用户唯一性校验
通过UserService.registerUser内部实现
- 检查用户名是否重复
- 检查手机号是否重复
- 检查邮箱是否重复
### 4. 注册后自动登录
- 注册成功后自动调用登录接口
- 返回完整的登录信息token、用户信息等
- 用户无需再次输入密码
## 数据库设计
### 用户表 (tb_sys_user)
| 字段 | 类型 | 说明 |
|------|------|------|
| ID | VARCHAR | 用户ID主键 |
| username | VARCHAR | 用户名 |
| password | VARCHAR | 加密后的密码 |
| email | VARCHAR | 邮箱 |
| phone | VARCHAR | 手机号 |
| wechatID | VARCHAR | 微信号 |
| status | INT | 用户状态0-正常1-禁用2-锁定) |
| createTime | DATETIME | 创建时间 |
| updateTime | DATETIME | 更新时间 |
| deleted | BOOLEAN | 是否删除 |
### 用户信息表 (tb_sys_user_info)
- 与用户表一对一关系
- 存储用户详细信息(头像、性别、姓名等)
- 注册时自动创建默认记录
## 错误码说明
| 错误码 | 错误信息 | 说明 |
|--------|----------|------|
| 500 | 密码不能为空 | 密码字段为空 |
| 500 | 密码至少6个字符 | 密码长度不足 |
| 500 | 两次输入的密码不一致 | 密码和确认密码不匹配 |
| 500 | 用户名不能为空 | 用户名注册时用户名为空 |
| 500 | 用户名长度为3-20个字符 | 用户名长度不符合要求 |
| 500 | 用户名只能包含字母、数字和下划线 | 用户名包含非法字符 |
| 500 | 手机号不能为空 | 手机号注册时手机号为空 |
| 500 | 手机号格式不正确 | 手机号格式错误 |
| 500 | 请输入手机验证码 | 手机验证码为空 |
| 500 | 验证码已过期,请重新获取 | 验证码不存在或已过期 |
| 500 | 验证码错误 | 验证码不正确 |
| 500 | 邮箱不能为空 | 邮箱注册时邮箱为空 |
| 500 | 邮箱格式不正确 | 邮箱格式错误 |
| 500 | 请输入邮箱验证码 | 邮箱验证码为空 |
| 500 | 用户已存在 | 用户名/手机号/邮箱已被注册 |
| 500 | 未知的注册类型 | registerType参数错误 |
## 前端集成示例
### 1. 用户名注册
```typescript
import { authApi } from '@/apis/system/auth';
const handleRegister = async () => {
const result = await authApi.register({
registerType: 'username',
username: 'zhangsan',
password: '123456',
confirmPassword: '123456',
agree: true
});
if (result.code === 200) {
// 注册成功保存token
localStorage.setItem('token', result.data.token);
// 跳转到首页
router.push('/');
}
};
```
### 2. 手机号注册
```typescript
// 发送验证码
const sendSmsCode = async () => {
const result = await authApi.sendSmsCode('13800138000');
if (result.code === 200) {
ElMessage.success('验证码已发送');
// 开始倒计时
startCountdown();
}
};
// 注册
const handleRegister = async () => {
const result = await authApi.register({
registerType: 'phone',
phone: '13800138000',
smsCode: '123456',
password: '123456',
confirmPassword: '123456',
agree: true
});
if (result.code === 200) {
ElMessage.success('注册成功');
// 保存token并跳转
}
};
```
### 3. 邮箱注册
```typescript
// 发送验证码
const sendEmailCode = async () => {
const result = await authApi.sendEmailCode('user@example.com');
if (result.code === 200) {
ElMessage.success('验证码已发送到邮箱');
// 开始倒计时
startCountdown();
}
};
// 注册
const handleRegister = async () => {
const result = await authApi.register({
registerType: 'email',
email: 'user@example.com',
emailCode: '123456',
password: '123456',
confirmPassword: '123456',
agree: true
});
if (result.code === 200) {
ElMessage.success('注册成功');
// 保存token并跳转
}
};
```
## 测试用例
### 1. 用户名注册测试
```bash
# 正常注册
curl -X POST http://localhost:8081/schoolNewsServ/auth/register \
-H "Content-Type: application/json" \
-d '{
"registerType": "username",
"username": "testuser",
"password": "123456",
"confirmPassword": "123456"
}'
# 用户名重复
curl -X POST http://localhost:8081/schoolNewsServ/auth/register \
-H "Content-Type: application/json" \
-d '{
"registerType": "username",
"username": "testuser",
"password": "123456",
"confirmPassword": "123456"
}'
# 预期:返回"用户已存在"
# 用户名过短
curl -X POST http://localhost:8081/schoolNewsServ/auth/register \
-H "Content-Type: application/json" \
-d '{
"registerType": "username",
"username": "ab",
"password": "123456",
"confirmPassword": "123456"
}'
# 预期:返回"用户名长度为3-20个字符"
```
### 2. 手机号注册测试
```bash
# 先发送验证码
curl -X POST http://localhost:8081/schoolNewsServ/auth/send-sms-code \
-H "Content-Type: application/json" \
-d '{"phone": "13800138000"}'
# 然后注册(使用日志中的验证码)
curl -X POST http://localhost:8081/schoolNewsServ/auth/register \
-H "Content-Type: application/json" \
-d '{
"registerType": "phone",
"phone": "13800138000",
"smsCode": "123456",
"password": "123456",
"confirmPassword": "123456"
}'
```
### 3. 邮箱注册测试
```bash
# 先发送验证码
curl -X POST http://localhost:8081/schoolNewsServ/auth/send-email-code \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com"}'
# 然后注册(检查邮箱获取验证码)
curl -X POST http://localhost:8081/schoolNewsServ/auth/register \
-H "Content-Type: application/json" \
-d '{
"registerType": "email",
"email": "test@example.com",
"emailCode": "123456",
"password": "123456",
"confirmPassword": "123456"
}'
```
## 注意事项
1. **验证码有效期**验证码10分钟后失效需要重新获取
2. **发送频率限制**:同一手机号/邮箱60秒内只能发送一次验证码
3. **密码安全**密码使用BCrypt加密存储不可逆
4. **自动登录**注册成功后自动登录前端需要保存返回的token
5. **用户名规则**
- 用户名注册:用户自定义
- 手机号注册:用户名=手机号
- 邮箱注册:用户名=邮箱前缀
6. **开发测试**:短信服务使用模拟模式时,验证码会在日志中输出
## 后续优化建议
1. 添加图形验证码,防止恶意发送验证码
2. 添加IP限流防止批量注册
3. 添加邀请码机制
4. 实现手机号和邮箱的绑定功能
5. 添加密码强度验证
6. 实现找回密码功能
7. 添加注册协议弹窗确认
8. 记录注册日志用于分析