forked from datawhale/whale-town-end
范围:src/core/login_core/ - 提取魔法数字为常量,提升代码可维护性 - 拆分过长方法,提升代码可读性 - 消除代码重复,优化方法结构 - 添加详细的类和方法注释 - 统一JWT配置常量管理 - 清理TODO项和未使用代码
7.3 KiB
7.3 KiB
LoginCore 登录核心模块
LoginCore 是 Whale Town 游戏服务器的用户认证核心模块,提供完整的用户登录、注册、密码管理、邮箱验证和JWT令牌管理功能,支持多种认证方式包括密码登录、验证码登录和 GitHub OAuth 登录。
对外提供的接口
login()
支持用户名/邮箱/手机号的密码登录,验证用户身份并返回认证结果。
verificationCodeLogin()
使用邮箱或手机验证码登录,提供无密码认证方式。
githubOAuth()
GitHub OAuth 第三方登录,支持新用户注册和现有用户信息更新。
register()
用户注册功能,支持邮箱验证和用户唯一性检查。
changePassword()
修改用户密码,验证旧密码并设置新密码。
resetPassword()
通过验证码重置密码,支持忘记密码场景。
sendPasswordResetCode()
发送密码重置验证码到用户邮箱或手机。
sendEmailVerification()
发送邮箱验证码,用于邮箱验证和注册流程。
verifyEmailCode()
验证邮箱验证码,完成邮箱验证流程。
resendEmailVerification()
重新发送邮箱验证码,处理验证码丢失情况。
sendLoginVerificationCode()
发送登录用验证码,支持验证码登录方式。
generateTokenPair()
生成JWT访问令牌和刷新令牌对,用于用户会话管理。
verifyToken()
验证JWT令牌有效性,支持访问令牌和刷新令牌验证。
refreshAccessToken()
使用刷新令牌生成新的访问令牌,实现无感知令牌续期。
deleteUser()
删除用户记录,用于注册失败时的回滚操作。
debugVerificationCode()
调试验证码信息,用于开发环境调试。
使用的项目内部依赖
UsersService (来自 core/db/users)
用户数据访问服务,提供用户的增删改查操作和唯一性验证。
EmailService (来自 core/utils/email)
邮件发送服务,用于发送验证码邮件、欢迎邮件和密码重置邮件。
VerificationService (来自 core/utils/verification)
验证码管理服务,提供验证码生成、验证、冷却时间管理等功能。
JwtService (来自 @nestjs/jwt)
JWT令牌服务,用于生成和验证JWT访问令牌。
ConfigService (来自 @nestjs/config)
配置管理服务,用于获取JWT密钥、过期时间等配置信息。
UserStatus (来自 core/db/users/user_status.enum)
用户状态枚举,定义用户的激活、禁用、待验证等状态值。
VerificationCodeType (来自 core/utils/verification)
验证码类型枚举,区分邮箱验证、短信验证、密码重置等不同用途。
核心特性
JWT令牌管理
- 生成访问令牌和刷新令牌对,支持Bearer认证
- 令牌签名验证,包含签发者和受众验证
- 自动令牌刷新机制,实现无感知续期
- 支持自定义过期时间配置(默认7天访问令牌,30天刷新令牌)
- 令牌载荷包含用户ID、用户名、角色等关键信息
多种认证方式
- 密码认证:支持用户名、邮箱、手机号登录
- 验证码认证:支持邮箱和短信验证码登录
- OAuth认证:支持GitHub第三方登录
- 统一的认证结果格式和异常处理
安全性保障
- 密码哈希存储(bcrypt,12轮盐值)
- 密码强度验证(最少8位,包含字母和数字)
- 用户状态检查,防止禁用用户登录
- 验证码冷却机制,防止频繁发送
- OAuth用户保护,防止密码操作
完整的用户生命周期
- 用户注册:支持邮箱验证和唯一性检查
- 邮箱验证:发送验证码和验证流程
- 密码管理:修改密码和重置密码
- 用户激活:自动发送欢迎邮件
灵活的验证码系统
- 支持邮箱和短信验证码
- 多种验证码用途(注册、登录、密码重置)
- 验证码冷却时间管理
- 测试模式支持,便于开发调试
异常处理完善
- 详细的错误分类和业务异常
- 用户友好的错误信息
- 完整的参数验证和边界检查
- 安全的异常信息,不泄露敏感数据
潜在风险
JWT令牌安全风险
- 令牌泄露可能导致身份冒用
- 刷新令牌有效期较长(30天)
- 建议实施令牌黑名单机制
- 缓解措施:HTTPS传输、安全存储、定期轮换
验证码安全风险
- 验证码在测试模式下会输出到控制台
- 邮件传输可能被拦截
- 验证码重放攻击风险
- 缓解措施:加密传输、一次性使用、时间限制
密码安全风险
- 当前密码策略相对简单(8位+字母数字)
- 缺少特殊字符和大小写要求
- 密码重置可能被滥用
- 缓解措施:增强密码策略、多因素认证、操作日志
用户枚举风险
- 登录失败信息可能泄露用户存在性
- 注册接口可能被用于用户枚举
- 密码重置可能泄露用户信息
- 缓解措施:统一错误信息、频率限制、验证码保护
第三方依赖风险
- GitHub OAuth 依赖外部服务可用性
- 邮件服务依赖第三方提供商
- 数据库连接异常影响认证
- 缓解措施:服务降级、重试机制、监控告警
并发安全风险
- 用户名冲突处理可能存在竞态条件
- 验证码并发验证可能导致状态不一致
- 令牌刷新并发可能产生多个有效令牌
- 缓解措施:数据库锁、原子操作、幂等性设计
使用示例
// 密码登录
const result = await loginCoreService.login({
identifier: 'user@example.com',
password: 'password123'
});
// 用户注册
const registerResult = await loginCoreService.register({
username: 'newuser',
password: 'password123',
nickname: '新用户',
email: 'user@example.com',
email_verification_code: '123456'
});
// 验证码登录
const codeLoginResult = await loginCoreService.verificationCodeLogin({
identifier: 'user@example.com',
verificationCode: '123456'
});
// GitHub OAuth登录
const oauthResult = await loginCoreService.githubOAuth({
github_id: 'github123',
username: 'githubuser',
nickname: 'GitHub用户',
email: 'user@example.com'
});
// 生成JWT令牌对
const tokenPair = await loginCoreService.generateTokenPair(user);
console.log(tokenPair.access_token); // JWT访问令牌
console.log(tokenPair.refresh_token); // JWT刷新令牌
// 验证JWT令牌
const payload = await loginCoreService.verifyToken(accessToken, 'access');
console.log(payload.sub); // 用户ID
console.log(payload.username); // 用户名
// 刷新访问令牌
const newTokenPair = await loginCoreService.refreshAccessToken(refreshToken);
// 发送邮箱验证码
const verificationResult = await loginCoreService.sendEmailVerification(
'user@example.com',
'用户昵称'
);
// 修改密码
const updatedUser = await loginCoreService.changePassword(
userId,
'oldPassword',
'newPassword123'
);
依赖服务
- UsersService: 用户数据访问服务,提供用户增删改查和唯一性验证
- EmailService: 邮件发送服务,用于验证码邮件和欢迎邮件发送
- VerificationService: 验证码管理服务,提供验证码生成、验证和冷却管理
- JwtService: JWT令牌服务,用于令牌生成和验证
- ConfigService: 配置管理服务,提供JWT密钥和过期时间配置
版本信息
- 版本: 1.1.0
- 作者: moyin
- 创建时间: 2025-12-17
- 最后修改: 2026-01-12