Files
backend/.qoder/repowiki/zh/content/API参考/认证API/认证API.md
lan a4b6c5011e
Some checks failed
SonarQube Analysis / sonarqube (push) Has been cancelled
chore(git): 更新.gitignore以忽略新的本地文件
2025-11-30 08:33:17 +08:00

460 lines
18 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.

# 认证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)