From f7c3983cc15e3d9d25505a8a6fa1748d5ac3063f Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Wed, 14 Jan 2026 12:00:19 +0800 Subject: [PATCH] =?UTF-8?q?refactor(auth):=20=E7=A7=BB=E9=99=A4Controller?= =?UTF-8?q?=EF=BC=8C=E4=B8=93=E6=B3=A8=E4=BA=8E=E4=B8=9A=E5=8A=A1=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 范围:src/business/auth/ 涉及文件: - src/business/auth/auth.module.ts - src/business/auth/README.md 主要改进: - 移除LoginController和RegisterController的导入和声明 - 调整模块结构,专注于业务逻辑层 - 更新README文档,明确Business Layer职责定位 - 完善依赖关系说明和架构层级描述 - 版本号从1.0.2升级到2.0.0(架构重构) --- src/business/auth/README.md | 468 ++++++++++++++++++------------- src/business/auth/auth.module.ts | 41 ++- 2 files changed, 302 insertions(+), 207 deletions(-) diff --git a/src/business/auth/README.md b/src/business/auth/README.md index 04b63c0..f800c15 100644 --- a/src/business/auth/README.md +++ b/src/business/auth/README.md @@ -1,246 +1,330 @@ - +业务层负责实现核心业务逻辑和流程控制: -# Auth 用户认证业务模块 +1. **业务流程**:实现完整的业务流程和规则 +2. **服务协调**:协调多个核心服务完成业务功能 +3. **数据转换**:将核心层数据转换为业务数据 +4. **业务验证**:实现业务规则验证 +5. **事务管理**:处理跨服务的事务逻辑 -Auth 是应用的核心用户认证业务模块,提供完整的用户登录、注册、密码管理、JWT令牌认证和GitHub OAuth集成功能,支持邮箱验证、验证码登录、安全防护和Zulip账号同步,具备完善的业务流程控制、错误处理和安全审计能力。 +## 模块组成 -## 用户认证功能 +``` +src/business/auth/ +├── login.service.ts # 登录业务服务 +├── register.service.ts # 注册业务服务 +├── auth.module.ts # 业务模块配置 +└── README.md # 模块文档 +``` -### login() -处理用户登录请求,支持用户名/邮箱/手机号登录,验证用户凭据并生成JWT令牌。 +## 对外提供的接口 -### register() -处理用户注册请求,支持邮箱验证,自动创建Zulip账号并建立关联。 +### LoginService -### githubOAuth() -处理GitHub OAuth登录,支持新用户自动注册和现有用户绑定。 +#### login(loginRequest: LoginRequest): Promise> +处理用户登录请求,验证用户凭据并生成JWT令牌,支持Zulip账号验证和更新。 -### verificationCodeLogin() -支持邮箱或手机号验证码登录,提供无密码登录方式。 +#### githubOAuth(oauthRequest: GitHubOAuthRequest): Promise> +使用GitHub账户登录或注册,自动创建用户账号并生成JWT令牌。 -## 密码管理功能 +#### verificationCodeLogin(loginRequest: VerificationCodeLoginRequest): Promise> +使用邮箱或手机号和验证码进行登录,无需密码即可完成认证。 -### sendPasswordResetCode() -发送密码重置验证码到用户邮箱或手机号,支持测试模式和真实发送模式。 +#### sendPasswordResetCode(identifier: string): Promise> +向用户邮箱或手机发送密码重置验证码,支持测试模式和真实发送模式。 -### resetPassword() -使用验证码重置用户密码,包含密码强度验证和安全检查。 +#### resetPassword(resetRequest: PasswordResetRequest): Promise +使用验证码重置用户密码,验证验证码有效性后更新密码。 -### changePassword() -修改用户密码,验证旧密码并应用新密码强度规则。 +#### changePassword(userId: bigint, oldPassword: string, newPassword: string): Promise +修改用户密码,需要验证旧密码正确性后才能更新为新密码。 -## 邮箱验证功能 +#### refreshAccessToken(refreshToken: string): Promise> +使用有效的刷新令牌生成新的访问令牌,实现无感知的令牌续期。 -### sendEmailVerification() -发送邮箱验证码,用于注册时的邮箱验证和账户安全验证。 +#### sendLoginVerificationCode(identifier: string): Promise> +向用户邮箱或手机发送登录验证码,用于验证码登录功能。 -### verifyEmailCode() -验证邮箱验证码,确认邮箱所有权并更新用户验证状态。 +### RegisterService -### resendEmailVerification() -重新发送邮箱验证码,处理验证码过期或丢失的情况。 +#### register(registerRequest: RegisterRequest): Promise> +处理用户注册请求,创建游戏账号和Zulip账号,支持邮箱验证和自动回滚。 -### sendLoginVerificationCode() -发送登录验证码,支持验证码登录功能。 +#### sendEmailVerification(email: string): Promise> +向指定邮箱发送验证码,支持测试模式和真实发送模式。 -## 调试和管理功能 +#### verifyEmailCode(email: string, code: string): Promise +验证邮箱验证码的有效性,用于邮箱验证流程。 -### debugVerificationCode() -获取验证码调试信息,用于开发环境的测试和调试。 +#### resendEmailVerification(email: string): Promise> +重新向指定邮箱发送验证码,用于验证码过期或未收到的情况。 -## HTTP API接口 +## 依赖关系 -### POST /auth/login -用户登录接口,接受用户名/邮箱/手机号和密码,返回JWT令牌和用户信息。 - -### POST /auth/register -用户注册接口,创建新用户账户并可选择性创建Zulip账号。 - -### POST /auth/github -GitHub OAuth登录接口,处理GitHub第三方登录和账户绑定。 - -### POST /auth/forgot-password -发送密码重置验证码接口,支持邮箱和手机号找回密码。 - -### POST /auth/reset-password -重置密码接口,使用验证码验证身份并设置新密码。 - -### PUT /auth/change-password -修改密码接口,需要验证旧密码并设置新密码。 - -### POST /auth/send-email-verification -发送邮箱验证码接口,用于邮箱验证流程。 - -### POST /auth/verify-email -验证邮箱验证码接口,确认邮箱所有权。 - -### POST /auth/resend-email-verification -重新发送邮箱验证码接口,处理验证码重发需求。 - -### POST /auth/verification-code-login -验证码登录接口,支持无密码登录方式。 - -### POST /auth/send-login-verification-code -发送登录验证码接口,为验证码登录提供验证码。 - -### POST /auth/refresh-token -刷新JWT令牌接口,使用刷新令牌获取新的访问令牌。 - -### POST /auth/debug-verification-code -调试验证码接口,获取验证码状态和调试信息。 - -### POST /auth/debug-clear-throttle -清除限流记录接口,仅用于开发环境调试。 - -## 认证和授权组件 - -### JwtAuthGuard -JWT认证守卫,验证请求中的Bearer令牌并提取用户信息到请求上下文。 - -### CurrentUser -当前用户装饰器,从请求上下文中提取认证用户信息,支持获取完整用户对象或特定属性。 +``` +Gateway Layer (auth.gateway.module) + ↓ 使用 +Business Layer (auth.module) + ↓ 依赖 +Core Layer (login_core.module, zulip_core.module) +``` ## 使用的项目内部依赖 -### LoginCoreService (来自 core/login_core/login_core.service) -登录核心服务,提供用户认证、密码管理、JWT令牌生成验证等核心功能实现。 +### LoginCoreService (来自 core/login_core) +核心登录服务,提供用户认证、JWT令牌生成、密码验证、验证码管理等技术实现。 -### ZulipAccountService (来自 core/zulip_core/services/zulip_account.service) -Zulip账号服务,处理Zulip账号的创建、管理和API Key安全存储。 +### ZulipAccountService (来自 core/zulip_core) +Zulip账号服务,提供Zulip账号创建、API Key管理、账号验证等功能。 -### ZulipAccountsService (来自 core/db/zulip_accounts/zulip_accounts.service) -Zulip账号数据服务,管理游戏用户与Zulip账号的关联关系数据。 +### ApiKeySecurityService (来自 core/zulip_core) +API Key安全服务,负责Zulip API Key的加密存储和Redis缓存管理。 -### ApiKeySecurityService (来自 core/zulip_core/services/api_key_security.service) -API Key安全服务,负责Zulip API Key的加密存储和安全管理。 +### ZulipAccountsService (来自 core/db/zulip_accounts) +Zulip账号数据访问服务,提供游戏账号与Zulip账号的关联管理。 -### Users (来自 core/db/users/users.entity) -用户实体类,定义用户数据结构和数据库映射关系。 +### Users (来自 core/db/users) +用户实体,定义用户数据结构和数据库映射关系。 -### UserStatus (来自 business/user_mgmt/user_status.enum) -用户状态枚举,定义用户的激活、禁用、待验证等状态值。 +## 核心原则 -### LoginDto, RegisterDto (本模块) -登录和注册数据传输对象,提供完整的数据验证规则和类型定义。 +### 1. 专注业务逻辑,不处理HTTP协议 -### LoginResponseDto, RegisterResponseDto (本模块) -登录和注册响应数据传输对象,定义API响应的数据结构和格式。 +```typescript +// ✅ 正确:返回统一的业务响应 +async login(loginRequest: LoginRequest): Promise> { + try { + // 1. 调用核心服务进行认证 + const authResult = await this.loginCoreService.login(loginRequest); + + // 2. 验证Zulip账号 + await this.validateAndUpdateZulipApiKey(authResult.user); + + // 3. 生成JWT令牌 + const tokenPair = await this.loginCoreService.generateTokenPair(authResult.user); + + // 4. 返回业务响应 + return { + success: true, + data: { user: this.formatUserInfo(authResult.user), ...tokenPair }, + message: '登录成功' + }; + } catch (error) { + return { + success: false, + message: error.message, + error_code: 'LOGIN_FAILED' + }; + } +} +``` -### ThrottlePresets, TimeoutPresets (来自 core/security_core/decorators) -安全防护预设配置,提供限流和超时控制的标准配置。 +### 2. 协调多个核心服务 + +```typescript +async register(registerRequest: RegisterRequest): Promise> { + // 1. 初始化Zulip管理员客户端 + await this.initializeZulipAdminClient(); + + // 2. 调用核心服务进行注册 + const authResult = await this.loginCoreService.register(registerRequest); + + // 3. 创建Zulip账号 + await this.createZulipAccountForUser(authResult.user, registerRequest.password); + + // 4. 生成JWT令牌 + const tokenPair = await this.loginCoreService.generateTokenPair(authResult.user); + + // 5. 返回完整的业务响应 + return { success: true, data: { ... }, message: '注册成功' }; +} +``` + +### 3. 统一的响应格式 + +```typescript +interface ApiResponse { + success: boolean; + data?: T; + message: string; + error_code?: string; +} +``` + +## 业务服务 + +### LoginService + +负责登录相关的业务逻辑: + +- `login()` - 用户登录 +- `githubOAuth()` - GitHub OAuth登录 +- `verificationCodeLogin()` - 验证码登录 +- `sendPasswordResetCode()` - 发送密码重置验证码 +- `resetPassword()` - 重置密码 +- `changePassword()` - 修改密码 +- `refreshAccessToken()` - 刷新访问令牌 +- `sendLoginVerificationCode()` - 发送登录验证码 + +### RegisterService + +负责注册相关的业务逻辑: + +- `register()` - 用户注册 +- `sendEmailVerification()` - 发送邮箱验证码 +- `verifyEmailCode()` - 验证邮箱验证码 +- `resendEmailVerification()` - 重新发送邮箱验证码 ## 核心特性 -### 多种登录方式支持 -- 用户名/邮箱/手机号密码登录 -- GitHub OAuth第三方登录 -- 邮箱/手机号验证码登录 -- 自动识别登录标识符类型 +### Zulip集成 +- **自动创建Zulip账号**:注册时同步创建Zulip聊天账号 +- **API Key管理**:安全存储和验证Zulip API Key +- **账号关联**:建立游戏账号与Zulip账号的映射关系 +- **失败回滚**:Zulip账号创建失败时自动回滚游戏账号 ### JWT令牌管理 -- 访问令牌和刷新令牌双令牌机制 -- 令牌自动刷新和过期处理 -- 安全的令牌签名和验证 -- 用户信息载荷和权限控制 +- **双令牌机制**:访问令牌(短期)+ 刷新令牌(长期) +- **无感知续期**:通过刷新令牌自动更新访问令牌 +- **令牌验证**:完整的令牌签名和过期时间验证 -### Zulip集成支持 -- 注册时自动创建Zulip账号 -- 游戏用户与Zulip账号关联管理 -- API Key安全存储和加密 -- 注册失败时的回滚机制 +### 统一响应格式 +- **ApiResponse接口**:统一的业务响应格式 +- **错误代码**:标准化的错误代码定义 +- **成功/失败标识**:明确的success字段 -### 邮箱验证系统 -- 注册时邮箱验证流程 -- 密码重置邮箱验证 -- 验证码生成和过期管理 -- 测试模式和生产模式支持 +### 数据转换和格式化 +- **用户信息格式化**:将Core层数据转换为业务数据 +- **BigInt处理**:自动将bigint类型转换为string +- **敏感信息过滤**:响应中不包含密码等敏感数据 -### 安全防护机制 -- 请求频率限制和防暴力破解 -- 密码强度验证和安全存储 -- 用户状态检查和权限控制 -- 详细的安全审计日志 +### 完整的错误处理 +- **业务异常捕获**:捕获所有业务逻辑异常 +- **详细日志记录**:记录操作ID、用户ID、错误信息、执行时间 +- **友好错误消息**:返回用户可理解的错误提示 -### 业务流程控制 -- 完整的错误处理和异常管理 -- 统一的响应格式和状态码 -- 业务规则验证和数据完整性 -- 操作日志和性能监控 +## 业务流程示例 + +### 用户注册流程 + +``` +1. 接收注册请求 + ↓ +2. 初始化Zulip管理员客户端 + ↓ +3. 调用LoginCoreService.register()创建游戏用户 + ↓ +4. 创建Zulip账号并建立关联 + ├─ 创建Zulip账号 + ├─ 获取API Key + ├─ 存储到Redis + └─ 创建数据库关联记录 + ↓ +5. 生成JWT令牌对 + ↓ +6. 返回注册成功响应 +``` + +### 用户登录流程 + +``` +1. 接收登录请求 + ↓ +2. 调用LoginCoreService.login()验证用户 + ↓ +3. 验证并更新Zulip API Key + ├─ 查找Zulip账号关联 + ├─ 从Redis获取API Key + ├─ 验证API Key有效性 + └─ 如果无效,重新生成 + ↓ +4. 生成JWT令牌对 + ↓ +5. 返回登录成功响应 +``` + +## 与其他层的交互 + +### 与Gateway层的交互 + +Gateway层调用Business层服务: + +```typescript +// Gateway Layer +@Post('login') +async login(@Body() loginDto: LoginDto, @Res() res: Response): Promise { + const result = await this.loginService.login({ + identifier: loginDto.identifier, + password: loginDto.password + }); + + this.handleResponse(result, res); +} +``` + +### 与Core层的交互 + +Business层调用Core层服务: + +```typescript +// Business Layer +async login(loginRequest: LoginRequest): Promise> { + // 调用核心服务 + const authResult = await this.loginCoreService.login(loginRequest); + const tokenPair = await this.loginCoreService.generateTokenPair(authResult.user); + + // 返回业务响应 + return { success: true, data: { ... } }; +} +``` + +## 最佳实践 + +1. **业务逻辑集中**:所有业务规则都在Business层实现 +2. **服务协调**:协调多个Core层服务完成复杂业务 +3. **错误处理**:捕获异常并转换为业务错误 +4. **日志记录**:记录关键业务操作和错误 +5. **事务管理**:处理跨服务的数据一致性 +6. **数据转换**:将Core层数据转换为业务数据 ## 潜在风险 ### Zulip账号创建失败风险 -- Zulip服务不可用时注册流程可能失败 -- 网络异常导致账号创建不完整 -- 建议实现重试机制和降级策略,允许跳过Zulip账号创建 +- **风险描述**:注册流程中Zulip账号创建可能失败 +- **影响范围**:导致注册流程中断,已创建的游戏账号需要回滚 +- **缓解措施**:完整的事务回滚机制和错误日志记录 -### 验证码发送依赖风险 -- 邮件服务配置错误导致验证码无法发送 -- 测试模式下验证码泄露到日志中 -- 建议完善邮件服务监控和测试模式安全控制 +### API Key验证失败风险 +- **风险描述**:登录时Zulip API Key可能已失效或不存在 +- **影响范围**:用户无法使用Zulip聊天功能 +- **缓解措施**:API Key验证失败不影响登录流程,记录警告日志,尝试重新生成 -### JWT令牌安全风险 -- 令牌泄露可能导致账户被盗用 -- 刷新令牌长期有效增加安全风险 -- 建议实现令牌黑名单机制和异常登录检测 +### 跨服务事务一致性风险 +- **风险描述**:涉及多个Core层服务的协调操作,部分操作成功部分失败 +- **影响范围**:数据不一致,如游戏账号创建成功但Zulip账号创建失败 +- **缓解措施**:明确的操作顺序、完整的错误处理、自动回滚机制 -### 并发操作风险 -- 同时注册相同用户名可能导致数据冲突 -- 高并发场景下验证码生成可能重复 -- 建议加强数据库唯一性约束和分布式锁机制 +### 业务逻辑复杂度风险 +- **风险描述**:登录和注册流程涉及多个步骤和服务,代码复杂度高 +- **影响范围**:增加维护难度,容易引入bug +- **缓解措施**:详细的注释、完整的测试覆盖(41个测试用例)、清晰的日志记录 -### 第三方服务依赖风险 -- GitHub OAuth服务不可用影响第三方登录 -- Zulip服务异常影响账号同步功能 -- 建议实现服务降级和故障转移机制 +### 验证码发送失败风险 +- **风险描述**:邮件服务不可用或配置错误导致验证码无法发送 +- **影响范围**:用户无法完成邮箱验证、密码重置、验证码登录 +- **缓解措施**:测试模式支持、详细的错误日志、邮件服务健康检查 -### 密码安全风险 -- 弱密码策略可能导致账户安全问题 -- 密码重置流程可能被恶意利用 -- 建议加强密码策略和增加二次验证机制 +## 注意事项 -## 补充信息 - -### 版本信息 -- 模块版本:1.0.2 -- 最后修改:2026-01-07 -- 作者:moyin -- 创建时间:2025-12-17 - -### 架构优化记录 -- 2026-01-07:将JWT技术实现从Business层移至Core层,符合分层架构原则 -- 2026-01-07:完成代码规范优化,统一注释格式和文件命名规范 -- 2026-01-07:完善测试覆盖,确保所有公共方法都有对应的单元测试 - -### 已知限制 -- 短信验证码功能尚未实现,目前仅支持邮箱验证码 -- Zulip账号创建失败时的重试机制有待完善 -- 多设备登录管理和会话控制功能待开发 - -### 改进建议 -- 实现短信验证码发送功能,完善多渠道验证 -- 增加社交登录支持(微信、QQ等) -- 实现多因素认证(MFA)提升账户安全 -- 添加登录设备管理和异常登录检测 -- 完善Zulip集成的错误处理和重试机制 \ No newline at end of file +- Business层不应该处理HTTP协议 +- Business层不应该直接访问数据库(通过Core层) +- Business层不应该包含技术实现细节 +- 所有业务逻辑都应该有完善的错误处理 +- 关键业务操作都应该有日志记录 diff --git a/src/business/auth/auth.module.ts b/src/business/auth/auth.module.ts index 0f0ebe5..782b9f5 100644 --- a/src/business/auth/auth.module.ts +++ b/src/business/auth/auth.module.ts @@ -1,32 +1,38 @@ /** * 用户认证业务模块 * + * 架构层级:Business Layer(业务层) + * * 功能描述: - * - 整合所有用户认证相关功能 - * - 用户登录、注册、密码管理 - * - GitHub OAuth集成 - * - 邮箱验证功能 - * - JWT令牌管理和验证 + * - 整合所有用户认证相关的业务逻辑 + * - 用户登录、注册、密码管理业务流程 + * - GitHub OAuth业务集成 + * - 邮箱验证业务功能 + * - Zulip账号关联业务 * * 职责分离: - * - 专注于认证业务模块的依赖注入和配置 - * - 整合核心服务和业务服务 - * - 提供JWT模块的统一配置 + * - 专注于业务逻辑实现和流程控制 + * - 整合核心服务完成业务功能 + * - 不包含HTTP协议处理(由Gateway层负责) + * - 不包含数据访问细节(由Core层负责) + * + * 依赖关系: + * - 依赖 Core Layer 的 LoginCoreModule + * - 依赖 Core Layer 的 ZulipCoreModule + * - 被 Gateway Layer 的 AuthGatewayModule 使用 * * 最近修改: + * - 2026-01-14: 架构重构 - 移除Controller,专注于业务逻辑层 * - 2026-01-07: 代码规范优化 - 文件夹扁平化,移除单文件文件夹结构 - * - 2026-01-07: 代码规范优化 - 更新注释规范,修正文件引用路径 * * @author moyin - * @version 1.0.2 + * @version 2.0.0 * @since 2025-12-24 - * @lastModified 2026-01-07 + * @lastModified 2026-01-14 */ import { Module } from '@nestjs/common'; -import { LoginController } from './login.controller'; import { LoginService } from './login.service'; -import { RegisterController } from './register.controller'; import { RegisterService } from './register.service'; import { LoginCoreModule } from '../../core/login_core/login_core.module'; import { ZulipCoreModule } from '../../core/zulip_core/zulip_core.module'; @@ -35,16 +41,21 @@ import { UsersModule } from '../../core/db/users/users.module'; @Module({ imports: [ + // 导入核心层模块 LoginCoreModule, ZulipCoreModule, ZulipAccountsModule.forRoot(), UsersModule, ], - controllers: [LoginController, RegisterController], providers: [ + // 业务服务 + LoginService, + RegisterService, + ], + exports: [ + // 导出业务服务供Gateway层使用 LoginService, RegisterService, ], - exports: [LoginService, RegisterService], }) export class AuthModule {} \ No newline at end of file