chore(git): 更新.gitignore以忽略新的本地文件
Some checks failed
SonarQube Analysis / sonarqube (push) Has been cancelled

This commit is contained in:
lan
2025-11-30 08:33:17 +08:00
parent 4b4980820f
commit a4b6c5011e
58 changed files with 19353 additions and 0 deletions

View File

@@ -0,0 +1,330 @@
# 发送验证码
<cite>
**本文引用的文件**
- [auth_handler.go](file://internal/handler/auth_handler.go)
- [routes.go](file://internal/handler/routes.go)
- [verification_service.go](file://internal/service/verification_service.go)
- [common.go](file://internal/types/common.go)
- [email.go](file://pkg/email/email.go)
- [manager.go](file://pkg/email/manager.go)
- [redis.go](file://pkg/redis/redis.go)
- [manager.go](file://pkg/redis/manager.go)
- [config.go](file://pkg/config/config.go)
- [main.go](file://cmd/server/main.go)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“发送验证码”API围绕 /api/v1/auth/send-code 端点进行完整说明。内容包括:
- 接口概述与HTTP规范
- 请求体结构与字段约束email、type
- 响应格式与错误码
- 验证码生成、存储与过期策略Redis
- 邮件服务集成pkg/email
- 不同验证码类型(注册、重置密码、更换邮箱)的处理逻辑
- 实际请求与响应示例
- 安全注意事项(频率限制、邮箱格式)
## 项目结构
/api/v1/auth/send-code 属于认证模块,位于 Gin 路由分组 /api/v1/auth 下,由处理器负责接收请求、绑定参数、调用服务层发送验证码,并通过 Redis 与邮件服务完成验证码的持久化与发送。
```mermaid
graph TB
Client["客户端"] --> Router["Gin 路由<br/>/api/v1/auth/send-code"]
Router --> Handler["处理器<br/>SendVerificationCode"]
Handler --> Service["服务层<br/>SendVerificationCode/VerifyCode"]
Service --> Redis["Redis 客户端<br/>存储验证码/频率限制"]
Service --> Email["邮件服务<br/>发送验证码邮件"]
Email --> SMTP["SMTP 服务器"]
```
图表来源
- [routes.go](file://internal/handler/routes.go#L16-L26)
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
- [verification_service.go](file://internal/service/verification_service.go#L40-L118)
- [redis.go](file://pkg/redis/redis.go#L60-L83)
- [email.go](file://pkg/email/email.go#L29-L105)
章节来源
- [routes.go](file://internal/handler/routes.go#L16-L26)
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
## 核心组件
- 路由与处理器
- 路由注册:/api/v1/auth/send-code 绑定到 SendVerificationCode 处理器。
- 处理器职责:参数绑定、调用服务层发送验证码、记录日志、返回统一响应。
- 服务层
- 生成6位数字验证码按 type 与 email 组合键存储至 Redis设置过期时间设置发送频率限制调用邮件服务发送对应类型的邮件。
- Redis
- 提供 Set/Get/Del/Exists 等基础操作,封装过期时间控制与错误处理。
- 邮件服务
- 基于 SMTP 的邮件发送,支持 465隐式 TLS与 587显式 TLS端口根据 type 选择不同主题与正文模板。
- 类型定义
- SendVerificationCodeRequest 包含 email 与 type 字段type 限定为 register/reset_password/change_email。
章节来源
- [routes.go](file://internal/handler/routes.go#L16-L26)
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
- [verification_service.go](file://internal/service/verification_service.go#L14-L24)
- [redis.go](file://pkg/redis/redis.go#L60-L83)
- [email.go](file://pkg/email/email.go#L29-L105)
- [common.go](file://internal/types/common.go#L49-L54)
## 架构总览
发送验证码的端到端流程如下:
```mermaid
sequenceDiagram
participant C as "客户端"
participant H as "处理器<br/>SendVerificationCode"
participant S as "服务层<br/>SendVerificationCode/VerifyCode"
participant R as "Redis 客户端"
participant E as "邮件服务<br/>SendVerificationCode"
participant M as "SMTP 服务器"
C->>H : POST /api/v1/auth/send-code<br/>{email, type}
H->>H : 绑定请求体并校验
H->>S : SendVerificationCode(ctx, redis, email, type)
S->>R : Exists(rate_limit_key)
alt 已存在
S-->>H : 返回“发送过于频繁”
H-->>C : 400 错误
else 不存在
S->>S : 生成6位数字验证码
S->>R : Set(code_key, code, 10分钟)
S->>R : Set(rate_limit_key, 1, 1分钟)
S->>E : 根据type发送邮件
E->>M : 发送邮件
M-->>E : 成功/失败
alt 邮件发送失败
S->>R : Del(code_key)
S-->>H : 返回“发送邮件失败”
H-->>C : 400 错误
else 成功
S-->>H : 返回成功
H-->>C : 200 成功
end
end
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
- [verification_service.go](file://internal/service/verification_service.go#L40-L118)
- [redis.go](file://pkg/redis/redis.go#L60-L83)
- [email.go](file://pkg/email/email.go#L29-L105)
## 详细组件分析
### HTTP 端点定义
- 方法POST
- 路径:/api/v1/auth/send-code
- 功能:根据邮箱与类型发送验证码邮件,并在 Redis 中存储验证码及频率限制。
章节来源
- [routes.go](file://internal/handler/routes.go#L16-L26)
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
### 请求体结构
- 字段
- email: 必填,需符合邮箱格式
- type: 必填,枚举值为 register/reset_password/change_email
- 参数绑定与校验
- 使用 Gin 的绑定与验证机制,确保 email 符合邮箱格式type 在允许范围内。
章节来源
- [common.go](file://internal/types/common.go#L49-L54)
### 响应格式
- 成功
- 状态码200
- 结构:统一响应体,包含 message 字段提示“验证码已发送,请查收邮件”
- 失败
- 状态码400
- 结构:统一错误响应体,包含错误码与错误信息
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
### 错误码与错误场景
- 400 参数错误
- 请求体绑定失败或参数校验失败
- 400 发送过于频繁
- Redis 中存在频率限制键1分钟内
- 400 邮件发送失败
- 邮件服务未启用或 SMTP 发送异常
- 400 验证码已过期或不存在
- 验证码校验时 Redis 中无对应键
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
- [verification_service.go](file://internal/service/verification_service.go#L40-L118)
### 验证码生成与存储Redis
- 生成规则
- 6位数字验证码
- 存储键
- 验证码键verification:code:{type}:{email}
- 过期时间10分钟
- 频率限制
- 频率限制键verification:rate_limit:{type}:{email}
- 过期时间1分钟
- Redis 操作
- Set/SetEx写入验证码与频率限制
- Get读取验证码用于校验
- Del验证成功后删除验证码键
- Exists检查是否处于发送冷却
章节来源
- [verification_service.go](file://internal/service/verification_service.go#L14-L24)
- [verification_service.go](file://internal/service/verification_service.go#L40-L118)
- [redis.go](file://pkg/redis/redis.go#L60-L83)
### 邮件服务集成pkg/email
- 初始化
- 通过全局初始化函数完成一次性初始化,随后通过 MustGetService 获取实例
- 发送逻辑
- 根据 type 选择不同主题与正文模板
- 支持 465隐式 TLS与 587显式 TLS两种端口模式
- 当邮件服务未启用时,返回“邮件服务未启用”的错误
- 主题与正文
- 注册:邮箱验证
- 重置密码:重置密码
- 更换邮箱:更换邮箱验证
- 默认:通用验证码
章节来源
- [email.go](file://pkg/email/email.go#L29-L105)
- [manager.go](file://pkg/email/manager.go#L1-L43)
- [main.go](file://cmd/server/main.go#L71-L74)
### 不同验证码类型的处理逻辑
- 注册register
- 邮件主题:邮箱验证
- 通常配合注册接口使用,注册时需提供验证码
- 重置密码reset_password
- 邮件主题:重置密码
- 与 /api/v1/auth/reset-password 配合使用
- 更换邮箱change_email
- 邮件主题:更换邮箱验证
- 与用户更换邮箱流程配合使用
- 默认(其他)
- 通用验证码主题
章节来源
- [verification_service.go](file://internal/service/verification_service.go#L106-L118)
- [email.go](file://pkg/email/email.go#L107-L139)
### 安全考虑
- 邮箱格式验证
- 请求体中 email 字段使用邮箱格式校验
- 发送频率限制
- Redis 中按 type+email 维度设置1分钟冷却避免刷屏
- 验证码有效期
- Redis 中验证码设置10分钟过期过期即失效
- 重复使用防护
- 验证码校验成功后立即删除键,防止二次使用
- 邮件服务开关
- 若未启用邮件服务,发送验证码会直接失败,避免泄露敏感信息
章节来源
- [common.go](file://internal/types/common.go#L49-L54)
- [verification_service.go](file://internal/service/verification_service.go#L40-L118)
- [redis.go](file://pkg/redis/redis.go#L60-L83)
- [email.go](file://pkg/email/email.go#L29-L40)
## 依赖关系分析
- 处理器依赖服务层
- 服务层依赖 Redis 与邮件服务
- 邮件服务依赖配置与日志
- Redis 客户端依赖配置与日志
- 全局初始化顺序:配置 -> 日志 -> 数据库 -> JWT -> Redis -> 对象存储 -> 邮件服务
```mermaid
graph LR
H["处理器<br/>auth_handler.go"] --> S["服务层<br/>verification_service.go"]
S --> R["Redis 客户端<br/>redis.go"]
S --> E["邮件服务<br/>email.go"]
E --> Cfg["配置<br/>config.go"]
E --> Lg["日志"]
R --> Cfg
R --> Lg
Main["服务启动<br/>main.go"] --> E
Main --> R
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
- [verification_service.go](file://internal/service/verification_service.go#L40-L118)
- [redis.go](file://pkg/redis/redis.go#L60-L83)
- [email.go](file://pkg/email/email.go#L29-L105)
- [config.go](file://pkg/config/config.go#L49-L107)
- [main.go](file://cmd/server/main.go#L27-L74)
章节来源
- [main.go](file://cmd/server/main.go#L27-L74)
## 性能考量
- Redis 操作均为 O(1)Set/Get/Del/Exists 均为常数时间复杂度
- 验证码长度固定为6位生成与比较成本低
- 邮件发送为外部依赖受网络与SMTP服务器性能影响
- 建议
- 合理设置 Redis 连接池大小PoolSize
- 控制邮件发送并发避免瞬时高峰导致SMTP限流
- 对高频请求开启更严格的频率限制(如增加冷却时间)
[本节为通用性能建议,不直接分析具体文件]
## 故障排查指南
- 400 参数错误
- 检查请求体是否包含 email 与 type且 type 是否在允许范围内
- 400 发送过于频繁
- 等待1分钟冷却时间或检查 Redis 中 rate_limit 键是否仍存在
- 400 邮件发送失败
- 确认邮件服务已启用EMAIL_ENABLED=true
- 检查 SMTP 配置(主机、端口、用户名、密码、发件人名称)
- 查看日志中 SMTP 发送错误信息
- 400 验证码已过期或不存在
- 检查 Redis 中 code 键是否存在与过期时间
- 确认验证码是否已被验证成功后删除
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
- [verification_service.go](file://internal/service/verification_service.go#L40-L118)
- [email.go](file://pkg/email/email.go#L29-L105)
- [redis.go](file://pkg/redis/redis.go#L60-L83)
## 结论
/api/v1/auth/send-code 端点通过 Gin 处理器接收请求调用服务层完成验证码生成、Redis 存储与频率限制、邮件发送等流程。其设计遵循最小暴露面原则:严格参数校验、冷却时间、过期时间与删除机制共同保障安全性与可用性。结合 pkg/email 与 pkg/redis 的稳定实现,整体具备良好的扩展性与可维护性。
[本节为总结性内容,不直接分析具体文件]
## 附录
### 请求与响应示例
- 请求示例
- 方法POST
- 路径:/api/v1/auth/send-code
- 请求体:
- email: user@example.com
- type: register 或 reset_password 或 change_email
- 成功响应示例
- 状态码200
- 响应体:包含 message 字段,提示“验证码已发送,请查收邮件”
- 失败响应示例
- 状态码400
- 响应体:包含错误码与错误信息,如“发送过于频繁,请稍后再试”或“发送邮件失败”
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
- [common.go](file://internal/types/common.go#L49-L54)

View File

@@ -0,0 +1,352 @@
# 用户注册
<cite>
**本文引用的文件**
- [auth_handler.go](file://internal/handler/auth_handler.go)
- [routes.go](file://internal/handler/routes.go)
- [common.go](file://internal/types/common.go)
- [response.go](file://internal/model/response.go)
- [user_service.go](file://internal/service/user_service.go)
- [verification_service.go](file://internal/service/verification_service.go)
- [password.go](file://pkg/auth/password.go)
- [user.go](file://internal/model/user.go)
- [auth_handler_test.go](file://internal/handler/auth_handler_test.go)
- [common_test.go](file://internal/types/common_test.go)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能与扩展性](#性能与扩展性)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“用户注册”API围绕 /api/v1/auth/register 端点进行完整说明。内容覆盖:
- HTTP 方法与路由
- 请求体字段与校验规则
- 响应格式与错误码
- 验证码机制与防暴力注册策略
- 密码加密存储流程
- 安全建议(密码强度、邮箱格式、防暴力注册)
## 项目结构
该功能由 Handler 层接收请求、Service 层执行业务逻辑、Model 层承载数据模型,并通过 JWT 生成登录令牌;验证码由 Redis 缓存并在邮件服务中发送。
```mermaid
graph TB
Client["客户端"] --> Routes["路由: /api/v1/auth/register"]
Routes --> Handler["处理器: Register"]
Handler --> VerifyCode["验证码校验: VerifyCode"]
Handler --> UserService["服务: RegisterUser"]
UserService --> Password["密码加密: HashPassword"]
UserService --> ModelUser["用户模型: User"]
UserService --> JWT["JWT 服务: GenerateToken"]
Handler --> Response["统一响应: Response/ErrorResponse"]
```
图表来源
- [routes.go](file://internal/handler/routes.go#L16-L26)
- [auth_handler.go](file://internal/handler/auth_handler.go#L17-L84)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [user_service.go](file://internal/service/user_service.go#L12-L68)
- [password.go](file://pkg/auth/password.go#L7-L21)
- [user.go](file://internal/model/user.go#L7-L21)
- [response.go](file://internal/model/response.go#L20-L73)
章节来源
- [routes.go](file://internal/handler/routes.go#L16-L26)
## 核心组件
- 路由与入口
- 路由位于 v1 组下的 /auth/register无需 JWT 即可访问。
- 请求体与校验
- 请求体字段username、email、password、avatar、verification_code。
- 校验规则:必填、长度/格式约束、验证码长度固定为6。
- 业务处理
- 验证码校验通过后,检查用户名/邮箱唯一性,加密密码,创建用户并生成 JWT。
- 响应与错误
- 成功返回包含 token 与用户信息的结构化响应;常见错误包括参数错误、验证码错误、用户名/邮箱已存在等。
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L17-L84)
- [common.go](file://internal/types/common.go#L33-L40)
- [response.go](file://internal/model/response.go#L20-L73)
- [user_service.go](file://internal/service/user_service.go#L12-L68)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
## 架构总览
注册流程的端到端调用序列如下:
```mermaid
sequenceDiagram
participant C as "客户端"
participant R as "路由"
participant H as "处理器 : Register"
participant VS as "验证码服务 : VerifyCode"
participant US as "用户服务 : RegisterUser"
participant PS as "密码服务 : HashPassword"
participant M as "用户模型 : User"
participant JS as "JWT服务 : GenerateToken"
participant RESP as "响应"
C->>R : POST /api/v1/auth/register
R->>H : 转发请求
H->>H : 解析并绑定请求体
H->>VS : 校验邮箱验证码
VS-->>H : 验证通过/失败
alt 验证失败
H-->>RESP : 返回400错误
else 验证通过
H->>US : 调用注册流程
US->>US : 检查用户名/邮箱唯一性
US->>PS : 加密密码
PS-->>US : 密文
US->>M : 创建用户记录
US->>JS : 生成JWT
JS-->>US : token
US-->>H : 返回用户与token
H-->>RESP : 返回200成功响应
end
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L27-L84)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [user_service.go](file://internal/service/user_service.go#L12-L68)
- [password.go](file://pkg/auth/password.go#L7-L21)
- [user.go](file://internal/model/user.go#L7-L21)
- [response.go](file://internal/model/response.go#L20-L73)
## 详细组件分析
### 接口定义与请求体
- 端点POST /api/v1/auth/register
- 请求体字段
- username必填长度3~50
- email必填邮箱格式
- password必填长度6~128
- avatar可选URL格式
- verification_code必填长度6
- 响应
- 成功:返回包含 token 与用户信息的结构化响应
- 失败:返回统一错误响应,包含业务码与消息
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L17-L84)
- [common.go](file://internal/types/common.go#L33-L40)
- [response.go](file://internal/model/response.go#L20-L73)
### 验证码机制与防暴力注册
- 验证码生成与存储
- 生成6位数字验证码有效期10分钟发送频率限制1分钟。
- 存储于 Redis键命名包含类型与邮箱。
- 验证流程
- 校验验证码是否存在且一致,一致即删除该验证码。
- 防暴力注册
- 发送频率限制键存在即拒绝重复发送,降低刷验证码风险。
- 注册接口对用户名/邮箱唯一性检查,避免重复注册。
```mermaid
flowchart TD
Start(["开始"]) --> Gen["生成6位验证码"]
Gen --> Store["写入Redis: 验证码键(10分钟)"]
Store --> RateLimit["写入Redis: 发送频率限制键(1分钟)"]
RateLimit --> Email["发送邮件"]
Email --> Verify["校验验证码"]
Verify --> Match{"是否匹配?"}
Match --> |否| Expired["返回错误: 验证码错误/过期"]
Match --> |是| Del["删除验证码键"]
Del --> Done(["结束"])
```
图表来源
- [verification_service.go](file://internal/service/verification_service.go#L26-L98)
章节来源
- [verification_service.go](file://internal/service/verification_service.go#L14-L24)
- [verification_service.go](file://internal/service/verification_service.go#L40-L77)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
### 密码加密与存储
- 加密方式bcrypt默认成本
- 存储:用户密码以密文形式保存,不返回明文
- 登录校验:使用 bcrypt 对比哈希
```mermaid
flowchart TD
In(["输入明文密码"]) --> Hash["bcrypt加密"]
Hash --> Out(["返回密文"])
Out --> Store["持久化存储"]
Store --> Login["登录时对比哈希"]
Login --> Ok["匹配成功"]
Login --> Fail["匹配失败"]
```
图表来源
- [password.go](file://pkg/auth/password.go#L7-L21)
- [user_service.go](file://internal/service/user_service.go#L32-L36)
- [user.go](file://internal/model/user.go#L7-L21)
章节来源
- [password.go](file://pkg/auth/password.go#L7-L21)
- [user_service.go](file://internal/service/user_service.go#L32-L36)
- [user.go](file://internal/model/user.go#L7-L21)
### 用户模型与唯一性约束
- 用户模型包含id、username、password、email、avatar、points、role、status、属性、登录时间、创建/更新时间等
- 唯一性约束username 与 email 在数据库层面唯一索引
- 注册时:若用户名或邮箱已存在,返回错误
```mermaid
erDiagram
USER {
bigint id PK
varchar username UK
varchar password
varchar email UK
varchar avatar
integer points
varchar role
smallint status
jsonb properties
timestamp last_login_at
timestamp created_at
timestamp updated_at
}
```
图表来源
- [user.go](file://internal/model/user.go#L7-L21)
章节来源
- [user.go](file://internal/model/user.go#L7-L21)
- [user_service.go](file://internal/service/user_service.go#L14-L31)
### 错误码与响应格式
- 成功200返回结构化响应包含 token 与用户信息
- 参数错误400请求体绑定失败或字段校验失败
- 验证码错误400验证码不存在/过期/不匹配
- 资源冲突409用户名或邮箱已存在
- 服务器错误500内部异常
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L27-L84)
- [response.go](file://internal/model/response.go#L20-L73)
- [user_service.go](file://internal/service/user_service.go#L14-L31)
### 安全考虑与最佳实践
- 密码强度
- 至少6位建议结合复杂度策略字母、数字、特殊字符
- 使用 bcrypt 存储,避免明文或弱加密
- 邮箱格式验证
- 使用框架内置邮箱格式校验
- 防暴力注册
- 验证码发送频率限制1分钟
- 验证码有效期10分钟过期自动失效
- 唯一性检查防止重复注册
- 传输安全
- 建议启用 HTTPS避免明文传输
- 日志与审计
- 记录注册失败与异常行为,便于追踪
章节来源
- [verification_service.go](file://internal/service/verification_service.go#L14-L24)
- [verification_service.go](file://internal/service/verification_service.go#L40-L77)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [user_service.go](file://internal/service/user_service.go#L14-L31)
- [password.go](file://pkg/auth/password.go#L7-L21)
## 依赖关系分析
- 处理器依赖
- 验证码服务:用于校验注册验证码
- 用户服务执行注册流程唯一性检查、密码加密、创建用户、生成JWT
- JWT 服务:生成登录令牌
- 服务依赖
- 密码服务bcrypt 加密与校验
- 数据模型:用户实体
- 工具与中间件
- 路由:定义 /api/v1/auth/register
- 统一响应:封装业务码与消息
```mermaid
graph LR
Handler["处理器: Register"] --> VS["验证码服务: VerifyCode"]
Handler --> US["用户服务: RegisterUser"]
US --> PS["密码服务: HashPassword"]
US --> Model["用户模型: User"]
US --> JWT["JWT服务: GenerateToken"]
Handler --> Resp["统一响应: Response/ErrorResponse"]
Route["路由: /api/v1/auth/register"] --> Handler
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L27-L84)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [user_service.go](file://internal/service/user_service.go#L12-L68)
- [password.go](file://pkg/auth/password.go#L7-L21)
- [user.go](file://internal/model/user.go#L7-L21)
- [response.go](file://internal/model/response.go#L20-L73)
- [routes.go](file://internal/handler/routes.go#L16-L26)
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L27-L84)
- [user_service.go](file://internal/service/user_service.go#L12-L68)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [password.go](file://pkg/auth/password.go#L7-L21)
- [user.go](file://internal/model/user.go#L7-L21)
- [response.go](file://internal/model/response.go#L20-L73)
- [routes.go](file://internal/handler/routes.go#L16-L26)
## 性能与扩展性
- 验证码缓存
- Redis 存储验证码与频率限制,具备高并发与低延迟特性
- 密码加密
- bcrypt 默认成本在安全性与性能间平衡,可根据硬件能力调整
- 扩展建议
- 引入速率限制中间件,对 /api/v1/auth/register 进一步限流
- 增加 IP/设备维度的风控策略
- 对高频失败场景增加验证码挑战或人机验证
[本节为通用建议,不直接分析具体文件]
## 故障排查指南
- 常见错误与定位
- 参数错误:检查请求体字段是否满足长度/格式要求
- 验证码错误:确认验证码是否过期、是否与发送邮箱一致
- 用户名/邮箱已存在:检查数据库唯一性约束
- 单元测试参考
- 注册请求体校验、错误处理与响应格式可通过测试用例验证
章节来源
- [auth_handler_test.go](file://internal/handler/auth_handler_test.go#L74-L116)
- [common_test.go](file://internal/types/common_test.go#L215-L287)
## 结论
用户注册 API 通过严格的请求体校验、验证码机制与 bcrypt 密码加密,提供了基础的安全保障。配合唯一性检查与频率限制,能够有效降低重复注册与暴力注册的风险。建议在生产环境中进一步完善风控策略与监控告警体系。
[本节为总结性内容,不直接分析具体文件]
## 附录
### 请求与响应示例(路径引用)
- 请求体字段与校验规则
- 字段定义与校验规则参见:[请求体定义](file://internal/types/common.go#L33-L40)
- 成功响应结构
- 成功响应结构参见:[统一响应](file://internal/model/response.go#L20-L73)
- 登录响应结构参见:[登录响应](file://internal/types/common.go#L107-L126)
- 错误响应结构
- 错误响应结构参见:[错误响应](file://internal/model/response.go#L20-L73)
- 路由与端点
- 注册路由参见:[路由定义](file://internal/handler/routes.go#L16-L26)
- 处理器与业务流程
- 注册处理器参见:[注册处理器](file://internal/handler/auth_handler.go#L27-L84)
- 注册业务流程参见:[注册服务](file://internal/service/user_service.go#L12-L68)
- 验证码与防暴力
- 验证码生成与校验参见:[验证码服务](file://internal/service/verification_service.go#L26-L98)
- 密码加密
- 密码加密与校验参见:[密码服务](file://pkg/auth/password.go#L7-L21)

View File

@@ -0,0 +1,351 @@
# 用户登录
<cite>
**本文引用的文件**
- [auth_handler.go](file://internal/handler/auth_handler.go)
- [routes.go](file://internal/handler/routes.go)
- [jwt.go](file://pkg/auth/jwt.go)
- [password.go](file://pkg/auth/password.go)
- [user_service.go](file://internal/service/user_service.go)
- [common.go](file://internal/types/common.go)
- [response.go](file://internal/model/response.go)
- [user.go](file://internal/model/user.go)
- [token.go](file://internal/model/token.go)
- [token_service.go](file://internal/service/token_service.go)
- [auth.go](file://internal/middleware/auth.go)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“用户登录”API围绕 /api/v1/auth/login 端点进行完整说明,覆盖:
- HTTP 方法与路由
- 请求体结构(用户名或邮箱登录)
- 响应格式包含JWT token与用户信息
- 错误码与错误处理
- JWT令牌生成流程访问令牌与声明
- 登录成功/失败后的审计日志记录IP、User-Agent
- 安全建议(防暴力破解、错误提示模糊化)
## 项目结构
该登录流程涉及以下模块协作:
- 路由层:注册 /api/v1/auth/login 路由
- 控制器层:处理登录请求、参数校验、调用服务层
- 服务层:用户查找、密码校验、令牌生成、登录日志记录
- 认证与密码JWT服务、bcrypt密码加解密
- 数据模型:用户、登录日志、令牌
- 中间件JWT认证中间件用于后续受保护接口
```mermaid
graph TB
Client["客户端"] --> Routes["路由注册<br/>/api/v1/auth/login"]
Routes --> Handler["控制器 Login()<br/>参数绑定/错误处理"]
Handler --> Service["服务层 LoginUser()<br/>查找用户/校验密码/生成JWT"]
Service --> JWT["JWT服务 GenerateToken()<br/>签发访问令牌"]
Service --> ModelUser["用户模型 User"]
Service --> ModelLog["登录日志 UserLoginLog"]
Handler --> Resp["统一响应 Response/ErrorResponse"]
Client --> Middleware["认证中间件 AuthMiddleware()<br/>Bearer Token 校验"]
```
图表来源
- [routes.go](file://internal/handler/routes.go#L16-L25)
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [jwt.go](file://pkg/auth/jwt.go#L32-L53)
- [user.go](file://internal/model/user.go#L1-L21)
- [user.go](file://internal/model/user.go#L52-L71)
- [auth.go](file://internal/middleware/auth.go#L12-L56)
章节来源
- [routes.go](file://internal/handler/routes.go#L16-L25)
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
## 核心组件
- 路由与控制器
- /api/v1/auth/login 由控制器 Login 处理负责参数绑定、IP/User-Agent采集、调用服务层并返回统一响应。
- 服务层
- LoginUser 支持用户名或邮箱登录校验用户状态与密码生成JWT更新最后登录时间记录成功/失败日志。
- 认证与密码
- JWT服务提供 GenerateToken/ValidateToken密码使用 bcrypt 进行哈希与校验。
- 数据模型
- User用户信息UserLoginLog登录审计日志Token令牌模型用于后续刷新/失效等场景)。
- 统一响应
- Response/ErrorResponse 提供统一的状态码与消息封装。
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [jwt.go](file://pkg/auth/jwt.go#L32-L53)
- [password.go](file://pkg/auth/password.go#L7-L21)
- [user.go](file://internal/model/user.go#L1-L21)
- [user.go](file://internal/model/user.go#L52-L71)
- [token.go](file://internal/model/token.go#L1-L15)
- [response.go](file://internal/model/response.go#L20-L53)
## 架构总览
登录端到端序列图POST /api/v1/auth/login
```mermaid
sequenceDiagram
participant C as "客户端"
participant R as "路由"
participant H as "控制器 Login()"
participant S as "服务层 LoginUser()"
participant J as "JWT服务"
participant U as "用户模型"
participant L as "登录日志"
C->>R : "POST /api/v1/auth/login"
R->>H : "进入 Login 控制器"
H->>H : "ShouldBindJSON 绑定请求体"
H->>S : "LoginUser(jwtService, username, password, ip, ua)"
S->>U : "根据用户名或邮箱查找用户"
S->>S : "校验用户状态"
S->>S : "bcrypt 校验密码"
S->>J : "GenerateToken(userID, username, role)"
J-->>S : "返回JWT字符串"
S->>U : "更新 last_login_at"
S->>L : "logSuccessLogin/logFailedLogin"
S-->>H : "返回 user, token"
H-->>C : "200 成功响应或401失败响应"
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [jwt.go](file://pkg/auth/jwt.go#L32-L53)
- [user.go](file://internal/model/user.go#L1-L21)
- [user.go](file://internal/model/user.go#L52-L71)
## 详细组件分析
### 接口定义与请求/响应
- HTTP 方法与路径
- 方法POST
- 路径:/api/v1/auth/login
- 请求体结构
- 字段username支持用户名或邮箱、password6-128字符
- 参数校验:必填、长度约束
- 响应格式
- 成功统一响应data 包含 token 与 userInfo
- 失败:统一错误响应,包含 code 与 message
- 错误码
- 400请求参数错误
- 401未授权用户名/邮箱或密码错误、账号被禁用等)
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [common.go](file://internal/types/common.go#L27-L31)
- [response.go](file://internal/model/response.go#L20-L53)
### 请求体结构与参数校验
- 请求体字段
- username支持用户名或邮箱
- password6-128字符
- 参数校验
- Gin 绑定时会触发结构体 tag 校验(必填、长度范围)
- 实际行为
- 控制器层在绑定失败时直接返回400
章节来源
- [common.go](file://internal/types/common.go#L27-L31)
- [auth_handler.go](file://internal/handler/auth_handler.go#L101-L109)
### 登录流程与JWT生成
- 登录流程要点
- 识别登录方式:包含@视为邮箱,否则为用户名
- 校验用户状态(仅状态为正常才允许登录)
- 使用 bcrypt 校验密码
- 生成JWT访问令牌包含用户ID、用户名、角色等声明
- 更新最后登录时间
- 记录登录日志(成功/失败均记录IP与User-Agent
- JWT声明内容
- 包含 user_id、username、role
- 默认包含过期时间、签发时间、生效时间、签发者等注册声明
- 令牌有效期
- 由JWT服务配置的过期小时数决定
```mermaid
flowchart TD
Start(["进入 LoginUser"]) --> Detect["判断登录方式<br/>用户名或邮箱"]
Detect --> FindUser["查找用户"]
FindUser --> Status{"用户状态正常?"}
Status -- 否 --> LogFail["记录失败日志<br/>原因:账号被禁用"]
LogFail --> ReturnErr["返回错误"]
Status -- 是 --> CheckPwd["bcrypt 校验密码"]
CheckPwd --> PwdOK{"密码正确?"}
PwdOK -- 否 --> LogFail2["记录失败日志<br/>原因:密码错误"]
LogFail2 --> ReturnErr
PwdOK -- 是 --> GenToken["GenerateToken(userID, username, role)"]
GenToken --> UpdateTime["更新 last_login_at"]
UpdateTime --> LogSuccess["记录成功日志"]
LogSuccess --> Done(["返回 user, token"])
ReturnErr --> Done
```
图表来源
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [jwt.go](file://pkg/auth/jwt.go#L32-L53)
- [password.go](file://pkg/auth/password.go#L16-L21)
- [user.go](file://internal/model/user.go#L1-L21)
- [user.go](file://internal/model/user.go#L52-L71)
章节来源
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [jwt.go](file://pkg/auth/jwt.go#L32-L53)
- [password.go](file://pkg/auth/password.go#L16-L21)
### 响应格式与错误码
- 成功响应
- data包含 token 与 userInfoid、username、email、avatar、points、role、status、last_login_at、created_at、updated_at
- 失败响应
- 400请求参数错误
- 401未授权用户名/邮箱或密码错误、账号被禁用)
- 统一响应封装
- Response/ErrorResponse 提供 code、message、data/error 字段
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L131-L147)
- [common.go](file://internal/types/common.go#L107-L126)
- [response.go](file://internal/model/response.go#L20-L53)
### 登录日志记录IP、User-Agent
- 记录内容
- 成功/失败均记录用户ID、IP地址、User-Agent、登录方式PASSWORD、是否成功、失败原因
- 记录时机
- 成功:登录成功后记录
- 失败:用户不存在、账号禁用、密码错误等情况下记录
- 存储位置
- 写入 user_login_logs 表
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L111-L129)
- [user_service.go](file://internal/service/user_service.go#L203-L226)
- [user.go](file://internal/model/user.go#L52-L71)
### 安全考虑与建议
- 防暴力破解
- 建议在网关或应用层增加速率限制例如基于IP或用户名的限流在失败时延长冷却时间或临时封禁
- 可结合验证码机制(当前登录接口未强制验证码,但注册/重置密码有验证码流程)
- 错误提示模糊化
- 当前服务层对“用户不存在/密码错误/账号禁用”均返回统一的“用户名/邮箱或密码错误”,避免泄露具体原因
- 令牌管理
- 当前登录仅返回JWT访问令牌若需刷新令牌可参考后续令牌服务刷新/失效等)能力
- 传输安全
- 建议仅在HTTPS下提供登录接口防止凭据被窃听
章节来源
- [user_service.go](file://internal/service/user_service.go#L88-L103)
- [auth_handler.go](file://internal/handler/auth_handler.go#L116-L129)
## 依赖关系分析
- 控制器依赖
- 控制器 Login 依赖JWT服务、日志、Redis注册流程、服务层 LoginUser
- 服务层依赖
- LoginUser 依赖用户仓库查找用户、JWT服务生成令牌、密码工具bcrypt、登录日志仓库写入日志
- 认证依赖
- JWT服务依赖golang-jwt库密码工具依赖bcrypt
- 模型依赖
- User、UserLoginLog、Token 模型用于数据持久化与审计
```mermaid
graph LR
H["控制器 Login()"] --> S["服务层 LoginUser()"]
H --> J["JWT服务 GenerateToken()"]
S --> U["User 模型"]
S --> L["UserLoginLog 模型"]
S --> P["bcrypt 密码校验"]
H --> R["路由 RegisterRoutes()"]
M["认证中间件 AuthMiddleware()"] --> J
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [jwt.go](file://pkg/auth/jwt.go#L32-L53)
- [password.go](file://pkg/auth/password.go#L16-L21)
- [user.go](file://internal/model/user.go#L1-L21)
- [user.go](file://internal/model/user.go#L52-L71)
- [routes.go](file://internal/handler/routes.go#L16-L25)
- [auth.go](file://internal/middleware/auth.go#L12-L56)
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [jwt.go](file://pkg/auth/jwt.go#L32-L53)
- [password.go](file://pkg/auth/password.go#L16-L21)
- [user.go](file://internal/model/user.go#L1-L21)
- [user.go](file://internal/model/user.go#L52-L71)
- [routes.go](file://internal/handler/routes.go#L16-L25)
- [auth.go](file://internal/middleware/auth.go#L12-L56)
## 性能考量
- 登录路径涉及数据库查询与密码校验,建议:
- 对用户表建立合适的索引username、email
- 密码校验使用 bcrypt默认成本适中可根据硬件能力调整
- 登录日志写入采用异步或批量策略当前为同步写入注意高并发下的I/O影响
- JWT生成与校验为CPU密集度较低的操作主要瓶颈在数据库与密码校验
## 故障排查指南
- 常见问题与定位
- 400 参数错误:检查请求体字段是否缺失或长度不符合要求
- 401 未授权:核对用户名/邮箱是否存在、账号状态是否正常、密码是否正确
- 登录日志未记录:确认日志写入是否成功,检查数据库连接与表结构
- 日志与审计
- 成功/失败日志均包含 IP 与 User-Agent便于追踪来源设备与来源网络
- 令牌相关
- 若后续引入刷新令牌,可参考令牌服务中的刷新/失效逻辑
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L101-L129)
- [user_service.go](file://internal/service/user_service.go#L203-L226)
- [response.go](file://internal/model/response.go#L20-L53)
## 结论
/api/v1/auth/login 提供了完整的用户名或邮箱登录能力具备参数校验、密码校验、JWT签发与登录日志记录。当前实现聚焦于登录流程本身后续可在速率限制、验证码、刷新令牌等方面进一步增强安全性与可用性。
## 附录
### API定义与示例
- 端点
- 方法POST
- 路径:/api/v1/auth/login
- 请求体
- username字符串必填支持用户名或邮箱
- password字符串必填长度6-128
- 成功响应
- code200
- data包含 token 与 userInfo
- 示例(结构示意)
- data: { token: "...", userInfo: { id, username, email, avatar, points, role, status, last_login_at, created_at, updated_at } }
- 失败响应
- 400请求参数错误
- 401未授权用户名/邮箱或密码错误、账号被禁用)
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [common.go](file://internal/types/common.go#L27-L31)
- [common.go](file://internal/types/common.go#L107-L126)
- [response.go](file://internal/model/response.go#L20-L53)
### JWT声明与令牌生命周期
- 声明内容
- user_id、username、role
- 过期时间、签发时间、生效时间、签发者等注册声明
- 令牌类型
- 当前登录返回访问令牌;刷新/失效等能力可参考令牌服务
章节来源
- [jwt.go](file://pkg/auth/jwt.go#L24-L53)
- [token_service.go](file://internal/service/token_service.go#L151-L238)

View File

@@ -0,0 +1,460 @@
# 认证API
<cite>
**本文引用的文件**
- [routes.go](file://internal/handler/routes.go)
- [auth_handler.go](file://internal/handler/auth_handler.go)
- [jwt.go](file://pkg/auth/jwt.go)
- [password.go](file://pkg/auth/password.go)
- [user_service.go](file://internal/service/user_service.go)
- [verification_service.go](file://internal/service/verification_service.go)
- [captcha_handler.go](file://internal/handler/captcha_handler.go)
- [captcha_service.go](file://internal/service/captcha_service.go)
- [auth.go](file://internal/middleware/auth.go)
- [common.go](file://internal/types/common.go)
- [email.go](file://pkg/email/email.go)
- [config.go](file://pkg/config/config.go)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向开发者系统性梳理认证API的设计与实现覆盖用户注册、登录、发送验证码与重置密码四个核心端点。文档基于路由分组与处理器实现详细说明每个API的HTTP方法、请求参数、响应格式与错误码重点解释JWT认证机制在登录流程中的作用以及验证码服务与邮箱服务的集成方式并提供实际请求/响应示例路径帮助快速理解认证流程。同时总结安全要点包括密码加密存储、JWT过期策略与防暴力破解措施。
## 项目结构
认证相关能力由“路由层-处理器层-服务层-基础设施层”四层构成:
- 路由层:在统一的路由组下挂载认证相关端点
- 处理器层:负责参数绑定、调用服务、组织响应与错误处理
- 服务层:封装业务逻辑(用户注册/登录、验证码发送与校验、密码变更等)
- 基础设施层JWT签发与校验、密码加解密、Redis验证码存储、SMTP邮件发送
```mermaid
graph TB
subgraph "路由层"
R["routes.go<br/>注册/auth路由组"]
end
subgraph "处理器层"
AH["auth_handler.go<br/>注册/登录/发送验证码/重置密码"]
CH["captcha_handler.go<br/>图形验证码生成/校验"]
end
subgraph "服务层"
US["user_service.go<br/>注册/登录/密码重置等"]
VS["verification_service.go<br/>验证码生成/发送/校验"]
CS["captcha_service.go<br/>图形验证码生成/校验"]
end
subgraph "基础设施层"
JWT["jwt.go<br/>JWT签发/校验"]
PW["password.go<br/>bcrypt加解密"]
EM["email.go<br/>SMTP邮件发送"]
CFG["config.go<br/>JWT/邮件/Redis等配置"]
end
R --> AH
R --> CH
AH --> US
AH --> VS
CH --> CS
US --> JWT
US --> PW
VS --> EM
VS --> CFG
CS --> CFG
```
图表来源
- [routes.go](file://internal/handler/routes.go#L16-L25)
- [auth_handler.go](file://internal/handler/auth_handler.go#L17-L249)
- [captcha_handler.go](file://internal/handler/captcha_handler.go#L1-L77)
- [user_service.go](file://internal/service/user_service.go#L12-L122)
- [verification_service.go](file://internal/service/verification_service.go#L14-L119)
- [captcha_service.go](file://internal/service/captcha_service.go#L18-L166)
- [jwt.go](file://pkg/auth/jwt.go#L10-L71)
- [password.go](file://pkg/auth/password.go#L1-L21)
- [email.go](file://pkg/email/email.go#L15-L163)
- [config.go](file://pkg/config/config.go#L67-L107)
章节来源
- [routes.go](file://internal/handler/routes.go#L16-L25)
## 核心组件
- 路由组与端点
- /api/v1/auth/registerPOST注册
- /api/v1/auth/loginPOST登录
- /api/v1/auth/send-codePOST发送验证码
- /api/v1/auth/reset-passwordPOST重置密码
- 中间件
- 认证中间件对受保护资源进行JWT校验
- 关键数据模型
- 请求/响应结构体定义于类型模块,包含登录、注册、验证码发送与重置密码等请求体与响应体字段
章节来源
- [routes.go](file://internal/handler/routes.go#L16-L25)
- [auth.go](file://internal/middleware/auth.go#L12-L56)
- [common.go](file://internal/types/common.go#L27-L61)
## 架构总览
认证API采用“路由-处理器-服务-基础设施”的分层设计,认证流程的关键交互如下:
```mermaid
sequenceDiagram
participant C as "客户端"
participant H as "处理器(auth_handler)"
participant S as "服务(user_service/verification_service)"
participant J as "JWT服务(pkg/auth)"
participant E as "邮件服务(pkg/email)"
participant R as "Redis"
rect rgb(255,255,255)
Note over C,H : 注册流程
C->>H : POST /api/v1/auth/register
H->>S : VerifyCode(验证码校验)
S->>R : GET verification : code : register : email
R-->>S : 验证码
S-->>H : 校验通过
H->>S : RegisterUser(创建用户+生成JWT)
S->>J : GenerateToken(userID, username, role)
J-->>S : token
S-->>H : 用户信息+token
H-->>C : 成功响应(包含token与用户信息)
end
rect rgb(255,255,255)
Note over C,H : 登录流程
C->>H : POST /api/v1/auth/login
H->>S : LoginUser(用户名/邮箱+密码)
S->>J : GenerateToken(userID, username, role)
J-->>S : token
S-->>H : 用户信息+token
H-->>C : 成功响应(包含token与用户信息)
end
rect rgb(255,255,255)
Note over C,H : 发送验证码流程
C->>H : POST /api/v1/auth/send-code
H->>S : SendVerificationCode(生成+存储+限流+发邮件)
S->>R : SET verification : code : type : email
S->>E : 发送邮件
E-->>S : 发送结果
S-->>H : 成功
H-->>C : 成功响应
end
rect rgb(255,255,255)
Note over C,H : 重置密码流程
C->>H : POST /api/v1/auth/reset-password
H->>S : VerifyCode(验证码校验)
S->>R : GET verification : code : reset_password : email
R-->>S : 验证码
S-->>H : 校验通过
H->>S : ResetUserPassword(更新密码)
S-->>H : 成功
H-->>C : 成功响应
end
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L17-L249)
- [user_service.go](file://internal/service/user_service.go#L12-L122)
- [verification_service.go](file://internal/service/verification_service.go#L40-L98)
- [jwt.go](file://pkg/auth/jwt.go#L32-L53)
- [email.go](file://pkg/email/email.go#L29-L55)
- [config.go](file://pkg/config/config.go#L67-L107)
## 详细组件分析
### 路由与端点
- 路由组
- /api/v1/auth认证相关端点
- /api/v1/user受JWT保护的用户资料端点不在本次文档范围
- 端点清单
- POST /api/v1/auth/register注册
- POST /api/v1/auth/login登录
- POST /api/v1/auth/send-code发送验证码
- POST /api/v1/auth/reset-password重置密码
章节来源
- [routes.go](file://internal/handler/routes.go#L16-L25)
### 注册接口POST /api/v1/auth/register
- 功能概述
- 接收用户名、邮箱、密码、验证码与可选头像校验验证码后创建用户并签发JWT
- 请求参数
- 字段username、email、password、verification_code、avatar
- 校验规则用户名长度、邮箱格式、密码长度、验证码长度、头像URL格式
- 响应格式
- 成功包含token与用户信息
- 失败:错误码与错误信息
- 错误码
- 400请求参数错误、验证码错误、用户名/邮箱已存在、密码加密失败、生成Token失败
- 安全要点
- 密码经bcrypt加密存储
- 验证码有效期短且一次性使用(校验通过即删除)
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L17-L84)
- [user_service.go](file://internal/service/user_service.go#L12-L68)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [password.go](file://pkg/auth/password.go#L1-L21)
- [common.go](file://internal/types/common.go#L33-L40)
### 登录接口POST /api/v1/auth/login
- 功能概述
- 支持用户名或邮箱登录校验密码后签发JWT并记录登录日志
- 请求参数
- 字段username支持用户名或邮箱、password
- 校验规则:必填、长度范围
- 响应格式
- 成功包含token与用户信息
- 失败401未授权
- 错误码
- 400请求参数错误
- 401用户名/邮箱或密码错误、账号被禁用
- 安全要点
- 密码使用bcrypt校验
- 登录成功更新最后登录时间
- 失败场景记录登录日志
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [password.go](file://pkg/auth/password.go#L16-L21)
- [common.go](file://internal/types/common.go#L27-L31)
### 发送验证码接口POST /api/v1/auth/send-code
- 功能概述
- 根据邮箱与类型(注册/重置密码/更换邮箱生成6位数字验证码存储至Redis并按类型限流随后通过SMTP发送邮件
- 请求参数
- 字段email、type枚举register/reset_password/change_email
- 校验规则邮箱格式、type枚举
- 响应格式
- 成功:通用成功响应
- 失败:错误码与错误信息
- 错误码
- 400请求参数错误、发送过于频繁、验证码已过期或不存在、验证码错误
- 安全要点
- 验证码有效期10分钟
- 发送频率限制1分钟/次
- 邮件服务可开关,未启用时跳过发送
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L149-L192)
- [verification_service.go](file://internal/service/verification_service.go#L14-L119)
- [email.go](file://pkg/email/email.go#L29-L55)
- [common.go](file://internal/types/common.go#L49-L54)
- [config.go](file://pkg/config/config.go#L67-L107)
### 重置密码接口POST /api/v1/auth/reset-password
- 功能概述
- 通过邮箱验证码校验后,更新用户密码
- 请求参数
- 字段email、verification_code、new_password
- 校验规则:邮箱格式、验证码长度、新密码长度
- 响应格式
- 成功:通用成功响应
- 失败400或500
- 错误码
- 400请求参数错误、验证码错误
- 500内部错误如用户不存在、密码加密失败
- 安全要点
- 密码经bcrypt加密存储
- 验证码一次性使用(校验通过即删除)
章节来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L194-L249)
- [user_service.go](file://internal/service/user_service.go#L166-L184)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [password.go](file://pkg/auth/password.go#L1-L21)
- [common.go](file://internal/types/common.go#L55-L61)
### JWT认证机制登录流程
- 生成与签发
- 登录成功后服务层调用JWT服务生成token包含用户ID、用户名、角色及标准声明过期时间、签发时间等
- 校验与中间件
- 中间件从Authorization头提取Bearer token并调用JWT服务校验校验通过后将用户信息写入上下文
- 过期策略
- JWT过期小时数来自配置默认值可通过环境变量设置
```mermaid
sequenceDiagram
participant C as "客户端"
participant H as "处理器(Login)"
participant S as "服务(LoginUser)"
participant J as "JWT服务"
participant M as "认证中间件"
C->>H : POST /api/v1/auth/login
H->>S : LoginUser(usernameOrEmail, password)
S->>J : GenerateToken(userID, username, role)
J-->>S : token
S-->>H : 用户信息+token
H-->>C : {token, user_info}
Note over C,M : 访问受保护资源
C->>M : 携带Authorization : Bearer token
M->>J : ValidateToken(token)
J-->>M : Claims
M-->>C : 放行
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L86-L147)
- [user_service.go](file://internal/service/user_service.go#L70-L122)
- [jwt.go](file://pkg/auth/jwt.go#L32-L71)
- [auth.go](file://internal/middleware/auth.go#L12-L56)
- [config.go](file://pkg/config/config.go#L67-L71)
章节来源
- [jwt.go](file://pkg/auth/jwt.go#L10-L71)
- [auth.go](file://internal/middleware/auth.go#L12-L56)
- [config.go](file://pkg/config/config.go#L67-L71)
### 验证码服务与邮箱服务集成
- 验证码生成与存储
- 生成6位数字验证码存储于Redis键名包含类型与邮箱有效期10分钟
- 发送频率限制1分钟/次,避免刷屏
- 邮件发送
- 根据类型选择不同主题与正文模板支持465/587端口TLS/STARTTLS
- 邮件服务可开关,未启用时跳过发送
- 图形验证码captcha
- 生成滑块拼图验证码主图与滑块图以Base64形式返回目标坐标保存在Redis验证时比较偏移容差
```mermaid
flowchart TD
Start(["开始"]) --> GenCode["生成6位数字验证码"]
GenCode --> StoreRedis["存储到Redis<br/>键: verification:code:{type}:{email}<br/>过期: 10分钟"]
StoreRedis --> RateLimit["设置发送频率限制<br/>键: verification:rate_limit:{type}:{email}<br/>过期: 1分钟"]
RateLimit --> SendMail["发送邮件(根据类型选择模板)"]
SendMail --> MailOK{"邮件发送成功?"}
MailOK --> |是| Done(["结束"])
MailOK --> |否| Clean["删除Redis验证码键"] --> Fail(["失败"])
subgraph "图形验证码"
GStart["生成滑块拼图验证码"] --> SaveCaptcha["保存目标坐标到Redis<br/>键: captcha:{id}<br/>过期: 5分钟"]
SaveCaptcha --> ReturnBase64["返回主图/滑块图Base64与captchaId"]
Verify["前端提交dx与captchaId"] --> LoadCaptcha["从Redis读取目标坐标"]
LoadCaptcha --> Compare["比较dx与目标坐标容差"]
Compare --> |通过| DelCaptcha["删除Redis记录"]
Compare --> |失败| Warn["返回失败"]
end
```
图表来源
- [verification_service.go](file://internal/service/verification_service.go#L26-L119)
- [email.go](file://pkg/email/email.go#L29-L105)
- [captcha_service.go](file://internal/service/captcha_service.go#L75-L166)
- [captcha_handler.go](file://internal/handler/captcha_handler.go#L1-L77)
章节来源
- [verification_service.go](file://internal/service/verification_service.go#L14-L119)
- [email.go](file://pkg/email/email.go#L29-L105)
- [captcha_service.go](file://internal/service/captcha_service.go#L18-L166)
- [captcha_handler.go](file://internal/handler/captcha_handler.go#L1-L77)
### 请求/响应示例(示例路径)
- 注册
- 请求POST /api/v1/auth/register
- 示例路径:[注册请求体定义](file://internal/types/common.go#L33-L40)
- 响应包含token与用户信息
- 登录
- 请求POST /api/v1/auth/login
- 示例路径:[登录请求体定义](file://internal/types/common.go#L27-L31)
- 响应包含token与用户信息
- 发送验证码
- 请求POST /api/v1/auth/send-code
- 示例路径:[发送验证码请求体定义](file://internal/types/common.go#L49-L54)
- 响应:通用成功响应
- 重置密码
- 请求POST /api/v1/auth/reset-password
- 示例路径:[重置密码请求体定义](file://internal/types/common.go#L55-L61)
- 响应:通用成功响应
章节来源
- [common.go](file://internal/types/common.go#L27-L61)
## 依赖关系分析
- 组件耦合
- 处理器依赖服务层服务层依赖JWT与密码工具、Redis与邮件服务
- 中间件依赖JWT服务统一拦截受保护资源
- 外部依赖
- Redis验证码存储与限流
- SMTP邮件发送
- JWT令牌签发与校验
- 循环依赖
- 未见循环依赖迹象
```mermaid
graph LR
AH["auth_handler.go"] --> US["user_service.go"]
AH --> VS["verification_service.go"]
CH["captcha_handler.go"] --> CS["captcha_service.go"]
US --> JWT["jwt.go"]
US --> PW["password.go"]
VS --> EM["email.go"]
VS --> CFG["config.go"]
CS --> CFG
M["auth.go"] --> JWT
```
图表来源
- [auth_handler.go](file://internal/handler/auth_handler.go#L17-L249)
- [user_service.go](file://internal/service/user_service.go#L12-L122)
- [verification_service.go](file://internal/service/verification_service.go#L14-L119)
- [captcha_handler.go](file://internal/handler/captcha_handler.go#L1-L77)
- [captcha_service.go](file://internal/service/captcha_service.go#L18-L166)
- [auth.go](file://internal/middleware/auth.go#L12-L56)
- [jwt.go](file://pkg/auth/jwt.go#L10-L71)
- [password.go](file://pkg/auth/password.go#L1-L21)
- [email.go](file://pkg/email/email.go#L15-L163)
- [config.go](file://pkg/config/config.go#L67-L107)
## 性能考量
- Redis命中率
- 验证码键短生命周期建议合理设置Redis内存与淘汰策略避免热键阻塞
- 邮件发送
- 异步化与重试策略可进一步优化(当前实现为同步发送),避免阻塞请求线程
- JWT负载
- Claims中仅包含必要字段减少token体积提升网络传输效率
- 登录日志
- 失败日志写入数据库可能带来IO压力建议结合异步队列或批量写入
## 故障排查指南
- 登录失败
- 现象401未授权
- 排查:确认用户名/邮箱是否存在、密码是否正确、账号状态是否正常
- 参考路径:[登录失败处理](file://internal/service/user_service.go#L84-L104)
- 验证码错误/过期
- 现象400错误
- 排查:确认验证码类型与邮箱匹配、是否在有效期内、是否被重复使用
- 参考路径:[验证码校验](file://internal/service/verification_service.go#L79-L98)
- 邮件发送失败
- 现象:发送验证码接口报错
- 排查检查邮件服务开关、SMTP配置、网络连通性
- 参考路径:[邮件发送](file://pkg/email/email.go#L29-L105)
- JWT无效
- 现象访问受保护资源401
- 排查确认Authorization头格式、token是否过期、签名是否正确
- 参考路径:[JWT校验](file://pkg/auth/jwt.go#L55-L71)
章节来源
- [user_service.go](file://internal/service/user_service.go#L84-L104)
- [verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [email.go](file://pkg/email/email.go#L29-L105)
- [jwt.go](file://pkg/auth/jwt.go#L55-L71)
## 结论
该认证API围绕“路由-处理器-服务-基础设施”清晰分层实现了完整的注册、登录、验证码与重置密码流程。JWT用于无状态鉴权bcrypt保障密码安全Redis与SMTP分别承担验证码与邮件能力。通过严格的参数校验、限流与一次性验证码使用策略有效提升了安全性与可用性。建议后续引入图形验证码与更完善的限流策略进一步增强抗暴力破解能力。
## 附录
- 安全最佳实践
- 密码加密始终使用bcrypt
- JWT过期合理设置过期时间短期会话建议缩短
- 验证码:短有效期、一次性使用、限流
- 传输安全生产环境强制HTTPS
- 日志脱敏:避免泄露敏感信息
- 环境变量与配置
- JWT密钥与过期小时数、邮件SMTP配置、Redis连接参数等均通过环境变量注入
章节来源
- [config.go](file://pkg/config/config.go#L67-L107)

View File

@@ -0,0 +1,343 @@
# 重置密码
<cite>
**本文引用的文件**
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go)
- [internal/handler/routes.go](file://internal/handler/routes.go)
- [internal/service/verification_service.go](file://internal/service/verification_service.go)
- [internal/service/user_service.go](file://internal/service/user_service.go)
- [pkg/auth/password.go](file://pkg/auth/password.go)
- [internal/types/common.go](file://internal/types/common.go)
- [internal/model/response.go](file://internal/model/response.go)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向开发者与测试人员系统化梳理“重置密码”API的完整实现与使用规范覆盖以下要点
- 接口定位与HTTP方法POST /api/v1/auth/reset-password
- 请求体字段与校验规则email、verificationCode、newPassword
- 响应格式与错误码:统一的业务状态码与错误消息
- 流程说明:验证码验证 → 密码加密更新 → 成功响应
- 安全考虑:验证码一次性使用、有效期控制、密码复杂度要求
## 项目结构
围绕“重置密码”的关键文件分布如下:
- 路由注册:在路由组中将 /api/v1/auth/reset-password 绑定到处理器
- 处理器:接收请求、绑定参数、调用服务层、返回统一响应
- 服务层:
- 验证码服务:生成、发送、验证、删除;验证码一次性使用与有效期控制
- 用户服务:根据邮箱查找用户并更新密码(密码经加密后持久化)
- 工具与模型:
- 密码工具bcrypt 加密与校验
- 请求类型ResetPasswordRequest 的字段与约束
- 响应模型:统一响应结构与常用状态码
```mermaid
graph TB
subgraph "接口层"
R["路由注册<br/>/api/v1/auth/reset-password"]
H["处理器<br/>ResetPassword"]
end
subgraph "服务层"
VS["验证码服务<br/>VerifyCode/Generate/Send/Delete"]
US["用户服务<br/>ResetUserPassword"]
end
subgraph "工具与模型"
PW["密码工具<br/>bcrypt 加密/校验"]
RT["请求类型<br/>ResetPasswordRequest"]
RM["响应模型<br/>统一响应/状态码"]
end
R --> H
H --> VS
H --> US
US --> PW
H --> RM
VS --> RM
RT --> H
```
图表来源
- [internal/handler/routes.go](file://internal/handler/routes.go#L16-L26)
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L194-L249)
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L98)
- [internal/service/user_service.go](file://internal/service/user_service.go#L166-L184)
- [pkg/auth/password.go](file://pkg/auth/password.go#L1-L21)
- [internal/types/common.go](file://internal/types/common.go#L55-L61)
- [internal/model/response.go](file://internal/model/response.go#L1-L86)
章节来源
- [internal/handler/routes.go](file://internal/handler/routes.go#L16-L26)
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L194-L249)
## 核心组件
- 接口路径与方法
- 方法POST
- 路径:/api/v1/auth/reset-password
- 请求体结构
- 字段:
- email字符串必填需符合邮箱格式
- verificationCode字符串必填长度必须为6
- newPassword字符串必填长度范围为6~128
- 校验来源:请求类型定义与处理器绑定校验
- 响应格式
- 成功统一响应结构code=200message=“操作成功”data为空或简要提示
- 失败:统一错误响应结构,包含业务状态码与错误消息
- 错误码
- 400请求参数错误如字段缺失、格式不符、长度不符
- 400验证码错误或已过期
- 500服务端内部错误如数据库异常
章节来源
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L194-L249)
- [internal/types/common.go](file://internal/types/common.go#L55-L61)
- [internal/model/response.go](file://internal/model/response.go#L27-L52)
## 架构总览
下图展示“重置密码”端到端调用链路与各模块职责。
```mermaid
sequenceDiagram
participant C as "客户端"
participant G as "Gin路由"
participant H as "处理器 ResetPassword"
participant VS as "验证码服务 VerifyCode"
participant US as "用户服务 ResetUserPassword"
participant PW as "密码工具 bcrypt"
participant DB as "数据库"
C->>G : "POST /api/v1/auth/reset-password"
G->>H : "路由转发"
H->>H : "绑定并校验请求体"
H->>VS : "VerifyCode(email, code, type=reset_password)"
VS-->>H : "验证通过/失败"
alt "验证码失败"
H-->>C : "400 错误响应"
else "验证码通过"
H->>US : "ResetUserPassword(email, newPassword)"
US->>PW : "HashPassword(newPassword)"
PW-->>US : "hashedPassword"
US->>DB : "UpdateUserFields(password=hashed)"
DB-->>US : "OK"
US-->>H : "OK"
H-->>C : "200 成功响应"
end
```
图表来源
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L194-L249)
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [internal/service/user_service.go](file://internal/service/user_service.go#L166-L184)
- [pkg/auth/password.go](file://pkg/auth/password.go#L1-L21)
## 详细组件分析
### 处理器ResetPassword
- 职责
- 绑定并校验请求体
- 调用验证码服务验证验证码(一次性使用)
- 调用用户服务更新密码(密码加密存储)
- 返回统一响应
- 关键行为
- 参数绑定失败返回400
- 验证码失败返回400
- 更新密码失败返回500
- 成功返回200
章节来源
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L194-L249)
### 验证码服务VerifyCode 与发送流程
- 验证码类型
- reset_password用于重置密码场景
- 一次性使用
- 验证通过后立即删除Redis中的验证码键值
- 有效期控制
- 默认10分钟
- 发送频率限制
- 同一邮箱同类型验证码在1分钟内不可重复发送
- 发送流程
- 生成6位数字验证码
- 写入Redis带过期时间
- 设置发送频率限制键
- 发送邮件(按类型区分模板)
```mermaid
flowchart TD
Start(["开始"]) --> Bind["绑定请求体"]
Bind --> Verify["VerifyCode(email, code, type)"]
Verify --> Check{"验证码正确且未过期?"}
Check --> |否| Err["返回400 错误"]
Check --> |是| Delete["删除Redis中的验证码键"]
Delete --> Next["进入下一步"]
Err --> End(["结束"])
Next --> End
```
图表来源
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L218-L230)
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L79-L98)
章节来源
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L14-L24)
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L98)
### 用户服务ResetUserPassword
- 流程
- 根据邮箱查询用户
- 对新密码进行bcrypt加密
- 更新用户记录的password字段
- 错误处理
- 用户不存在:返回错误
- 加密失败:返回错误
- 数据库更新失败:返回错误
```mermaid
flowchart TD
S(["开始"]) --> Find["根据邮箱查找用户"]
Find --> Found{"找到用户?"}
Found --> |否| E1["返回错误:用户不存在"]
Found --> |是| Hash["HashPassword(newPassword)"]
Hash --> HOK{"加密成功?"}
HOK --> |否| E2["返回错误:密码加密失败"]
HOK --> |是| Update["UpdateUserFields(password=hashed)"]
Update --> UOK{"更新成功?"}
UOK --> |否| E3["返回错误:数据库更新失败"]
UOK --> |是| OK["返回成功"]
E1 --> End(["结束"])
E2 --> End
E3 --> End
OK --> End
```
图表来源
- [internal/service/user_service.go](file://internal/service/user_service.go#L166-L184)
- [pkg/auth/password.go](file://pkg/auth/password.go#L1-L21)
章节来源
- [internal/service/user_service.go](file://internal/service/user_service.go#L166-L184)
- [pkg/auth/password.go](file://pkg/auth/password.go#L1-L21)
### 请求体与响应模型
- 请求体字段与约束
- email必填邮箱格式
- verificationCode必填长度6
- newPassword必填长度6~128
- 响应模型
- 成功code=200message=“操作成功”
- 失败code=400或500message=错误描述
章节来源
- [internal/types/common.go](file://internal/types/common.go#L55-L61)
- [internal/model/response.go](file://internal/model/response.go#L27-L52)
## 依赖关系分析
- 路由到处理器
- /api/v1/auth/reset-password → ResetPassword
- 处理器到服务层
- ResetPassword → VerifyCode验证码验证
- ResetPassword → ResetUserPassword密码更新
- 服务层到工具
- ResetUserPassword → HashPasswordbcrypt加密
- 服务层到存储
- ResetUserPassword → UpdateUserFields持久化
```mermaid
graph LR
Routes["路由"] --> Handler["处理器 ResetPassword"]
Handler --> VS["验证码服务"]
Handler --> US["用户服务"]
US --> PW["密码工具 bcrypt"]
US --> DB["数据库"]
```
图表来源
- [internal/handler/routes.go](file://internal/handler/routes.go#L16-L26)
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L194-L249)
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [internal/service/user_service.go](file://internal/service/user_service.go#L166-L184)
- [pkg/auth/password.go](file://pkg/auth/password.go#L1-L21)
章节来源
- [internal/handler/routes.go](file://internal/handler/routes.go#L16-L26)
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L194-L249)
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L79-L98)
- [internal/service/user_service.go](file://internal/service/user_service.go#L166-L184)
- [pkg/auth/password.go](file://pkg/auth/password.go#L1-L21)
## 性能考量
- 验证码存储与访问
- Redis作为验证码缓存具备高并发读写能力建议合理设置过期时间与限流键避免热点攻击
- 密码加密成本
- bcrypt默认成本较高单次加密有一定CPU开销建议在高并发场景下关注服务实例的CPU占用与延迟
- 数据库更新
- 单字段更新通常很快;建议确保数据库连接池配置合理,避免阻塞
## 故障排查指南
- 常见错误与定位
- 400 参数错误:检查请求体字段是否齐全、格式是否正确、长度是否满足约束
- 400 验证码错误/过期:确认验证码是否正确、是否已被使用(一次性)、是否超过有效期
- 500 服务器错误:检查用户是否存在、密码加密是否成功、数据库更新是否异常
- 日志与追踪
- 处理器对失败场景会输出警告/错误日志,便于定位问题
- 验证码生命周期
- 验证通过即删除,确保验证码只能使用一次
- 过期时间为10分钟超过后无法再使用
章节来源
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L218-L249)
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L79-L98)
## 结论
“重置密码”API以清晰的职责划分与严格的参数校验保障了安全性与可用性。验证码一次性使用与有效期控制有效降低了滥用风险密码采用bcrypt加密存储符合安全最佳实践。统一的响应模型与错误码体系提升了接口一致性与可观测性。
## 附录
### 请求与响应示例
- 请求示例JSON
- POST /api/v1/auth/reset-password
- Body
- email字符串必填邮箱格式
- verificationCode字符串必填长度6
- newPassword字符串必填长度6~128
- 成功响应示例JSON
- Status200
- Body
- code200
- message“操作成功”
- data空对象或简要提示
- 失败响应示例JSON
- Status400 或 500
- Body
- code400 或 500
- message错误描述
- error详细错误信息开发环境
章节来源
- [internal/types/common.go](file://internal/types/common.go#L55-L61)
- [internal/model/response.go](file://internal/model/response.go#L27-L52)
- [internal/handler/auth_handler.go](file://internal/handler/auth_handler.go#L218-L249)
### 安全考虑
- 验证码一次性使用
- 验证通过后立即删除Redis中的验证码键防止复用
- 验证码有效期控制
- 默认10分钟超时即失效
- 发送频率限制
- 同一邮箱同类型验证码在1分钟内不可重复发送
- 密码复杂度要求
- newPassword长度范围为6~128建议结合业务策略进一步增强复杂度例如包含大小写字母、数字与特殊字符当前实现以长度约束为主
章节来源
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L14-L24)
- [internal/service/verification_service.go](file://internal/service/verification_service.go#L40-L98)
- [internal/types/common.go](file://internal/types/common.go#L55-L61)