认证系统文档
1. 认证系统概述
Penny Lens Serverless 项目采用统一的认证系统,支持多平台登录(支付宝、微信等)以及邮箱/密码登录方式。本系统基于 JWT (JSON Web Token) 实现用户身份验证,并提供完善的会话管理机制。
2. 核心功能
- 统一登录接口: 支持多平台身份验证的统一入口
- JWT Token 认证: 基于 JWT 的安全认证机制
- 会话管理: 支持多设备登录、会话刷新和注销
- 密码加密: 采用 bcrypt 算法对用户密码进行加密存储
- 第三方平台集成: 支持支付宝、微信等平台的 OAuth 认证
- 权限验证: 细粒度的用户权限验证机制
3. 数据模型
3.1 用户模型 (User)
interface User {
_id?: string; // 用户唯一标识
username: string; // 用户名
password: string; // 加密后的密码
email?: string; // 邮箱
avatar?: string; // 头像 URL
phoneNumber?: string; // 电话号码
userType: UserType; // 用户类型
status: UserStatus; // 用户状态
createdAt: number; // 创建时间戳
updatedAt: number; // 更新时间戳
delFlag: boolean; // 软删除标记
lastLoginAt?: number; // 最后登录时间
currentSessionId?: string; // 当前会话ID
}3.2 会话模型 (Session)
interface Session {
_id?: string; // 会话ID
userId: string; // 关联的用户ID
token: string; // JWT Token
deviceId?: string; // 设备唯一标识
deviceInfo?: string; // 设备信息
ipAddress?: string; // IP地址
loginTime: number; // 登录时间
expireTime: number; // 过期时间
status: SessionStatus; // 会话状态
platform?: LoginPlatform; // 登录平台
}3.3 登录记录模型 (UserLoginRecord)
interface UserLoginRecord {
_id?: string; // 记录ID
userId: string; // 用户ID
loginTime: number; // 登录时间
platform: LoginPlatform; // 登录平台
deviceId?: string; // 设备ID
deviceInfo?: string; // 设备信息
ipAddress?: string; // IP地址
success: boolean; // 登录是否成功
errorMessage?: string; // 失败原因
}4. 统一登录服务
4.1 UnifiedLoginService 概述
UnifiedLoginService 是认证系统的核心服务,提供统一的登录入口和会话管理功能。该服务负责处理不同登录方式的身份验证逻辑,并生成统一的 JWT Token 返回给客户端。
4.2 主要方法
class UnifiedLoginService extends BaseService {
/**
* 统一登录方法
* @param params 登录参数
* @returns 登录结果,包含用户信息和Token
*/
public async login(params: UnifiedLoginRequest): Promise<UserResponse> {}
/**
* 验证JWT Token
* @param token JWT Token字符串
* @returns 验证结果,包含用户信息
*/
public async verifyToken(token: string): Promise<VerifyTokenResult> {}
/**
* 刷新会话Token
* @param token 当前Token
* @returns 新的Token
*/
public async refreshToken(token: string): Promise<string> {}
/**
* 注销登录
* @param token 当前Token
*/
public async logout(token: string): Promise<void> {}
}5. 登录流程详解
5.1 统一登录流程
- 请求处理: 客户端发送包含登录信息的请求到
/api接口,指定action: "user.login" - 路由分发:
router.ts根据 action 找到对应的UserController.login方法 - 参数验证:
UserController验证请求参数的合法性 - 登录处理: 调用
UnifiedLoginService.login处理登录逻辑 - 平台认证: 根据
platform字段调用相应的第三方认证方法(如微信或支付宝) - 用户匹配: 查找或创建对应的用户记录
- 会话创建: 生成 JWT Token,创建新的会话记录
- 响应返回: 返回包含用户信息和 Token 的响应
5.2 Token 验证流程
- 请求拦截: 对于需要认证的路由,
router.ts会拦截请求并提取 Token - Token 解析: 使用
jsonwebtoken库解析 Token - Token 验证: 验证 Token 的有效性,包括签名和过期时间
- 会话验证: 验证 Token 对应的会话是否有效
- 用户验证: 验证用户状态是否正常
- 权限检查: 检查用户是否有权限访问请求的资源
- 请求放行: 验证通过后,将用户信息附加到请求中并放行
6. 登录方式详解
6.1 邮箱/密码登录
请求参数:
interface UserLoginRequest {
email: string; // 用户邮箱
password: string; // 用户密码
platform: "email"; // 登录平台
deviceId?: string; // 设备ID
deviceInfo?: string; // 设备信息
}处理流程:
- 根据邮箱查询用户
- 验证密码是否匹配(使用 bcrypt 比较)
- 生成登录凭证
6.2 微信登录
请求参数:
interface WechatLoginRequest {
code: string; // 微信授权码
platform: "wechat"; // 登录平台
deviceId?: string; // 设备ID
deviceInfo?: string; // 设备信息
}处理流程:
- 使用微信授权码调用微信 API 获取 openId
- 根据 openId 查询或创建用户
- 生成登录凭证
6.3 支付宝登录
请求参数:
interface AlipayLoginRequest {
authCode: string; // 支付宝授权码
platform: "alipay"; // 登录平台
deviceId?: string; // 设备ID
deviceInfo?: string; // 设备信息
}处理流程:
- 使用支付宝授权码调用支付宝 API 获取 userId
- 根据 userId 查询或创建用户
- 生成登录凭证
7. 会话管理
7.1 Token 生成
JWT Token 使用项目配置中的 jwtSecret 进行签名,有效期默认为 7 天(可通过 jwtExpiresIn 配置)。Token 包含以下信息:
- iss: 签发者
- sub: 主题(用户ID)
- exp: 过期时间
- iat: 签发时间
- jti: JWT ID(会话唯一标识)
7.2 会话控制
- 多设备登录: 支持同一账号在多个设备上登录
- 会话上限: 可配置单个账号的最大会话数
- 会话踢出: 支持强制下线指定会话
- 会话状态: 会话可处于活跃、已过期、已销毁等状态
7.3 Token 刷新机制
当 Token 即将过期时,客户端可以使用当前有效的 Token 请求刷新,获取新的 Token 而无需重新登录。刷新 Token 的条件:
- 当前 Token 仍在有效期内
- Token 对应的会话仍处于活跃状态
- 用户状态正常
8. 安全机制
8.1 密码安全
- 密码加密: 使用 bcrypt 算法对用户密码进行加密存储,不可逆
- 密码策略: 建议实施密码复杂度要求(长度、字符组合等)
- 密码历史: 可选实现密码历史记录,避免重复使用旧密码
- 敏感操作验证: 重要操作需要重新验证密码
8.2 Token 安全
- HTTPS 传输: 所有含 Token 的请求必须通过 HTTPS 协议传输
- Token 存储: 客户端应使用安全的方式存储 Token,避免 XSS 攻击
- Token 验证: 服务端每次请求都验证 Token 的有效性
- Token 泄露处理: 支持主动失效特定 Token
8.3 安全防护
- 输入验证: 所有用户输入都进行严格的验证和过滤
- 请求频率限制: 对登录等敏感操作实施请求频率限制,防止暴力破解
- 异常日志: 记录登录失败、异常访问等安全相关事件
- IP 异常检测: 检测并处理异常 IP 访问
9. API 接口说明
9.1 统一登录接口
请求:
{
"action": "user.login",
"params": {
"platform": "email", // 或 "wechat", "alipay"
"email": "user@example.com",
"password": "password123",
"deviceId": "device123",
"deviceInfo": "iOS 15.0, iPhone 13"
}
}响应:
{
"code": 200,
"message": "登录成功",
"data": {
"id": "61c0c50b6d1b2c001fd2a345",
"username": "user123",
"email": "user@example.com",
"avatar": "https://example.com/avatar.jpg",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"createdAt": 1639149835278,
"updatedAt": 1642345678901
}
}9.2 Token 验证接口
请求:
{
"action": "user.verifyToken",
"params": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}响应:
{
"code": 200,
"message": "验证成功",
"data": {
"valid": true,
"userId": "61c0c50b6d1b2c001fd2a345",
"username": "user123",
"expiresAt": 1644923456789
}
}9.3 注销登录接口
请求:
{
"action": "user.logout",
"params": {}
}响应:
{
"code": 200,
"message": "注销成功",
"data": null
}10. 错误处理
10.1 常见错误类型
- 认证失败: 用户名或密码错误,Token 无效或已过期
- 权限不足: 用户尝试访问无权限的资源
- 会话异常: 会话已被销毁、用户已被禁用
- 请求频率过高: 短时间内登录尝试次数过多
- 参数验证失败: 输入参数格式不正确或缺失
10.2 错误码与消息
| 错误码 | 错误类型 | 错误消息 | 处理建议 |
|---|---|---|---|
| 400 | ValidationException | 参数验证失败 | 检查输入参数是否正确 |
| 401 | UnauthorizedException | 未授权访问 | 请先登录获取有效Token |
| 403 | ForbiddenException | 权限不足 | 检查用户权限 |
| 404 | NotFoundException | 用户不存在 | 确认用户是否已注册 |
| 500 | DatabaseException | 数据库操作失败 | 稍后重试或联系管理员 |
11. 开发与集成指南
11.1 前端集成
- 登录请求: 调用统一登录接口,传入正确的平台和凭证信息
- Token 存储: 使用安全的方式存储返回的 Token(如 localStorage + HTTP Only Cookie)
- 请求拦截: 为所有需要认证的请求添加 Token 头
- Token 刷新: 实现 Token 自动刷新机制,避免用户频繁登录
- 注销处理: 实现注销功能,清除存储的 Token
11.2 后端集成
- 路由配置: 在
routes.ts中正确设置requireAuth属性 - 权限验证: 使用
validateUserAccess方法验证用户权限 - 异常处理: 使用
wrapAsync包装异步方法,统一处理异常 - 会话管理: 合理使用会话管理相关的服务方法
12. 最佳实践
- 安全性优先: 始终将安全性放在首位,遵循最小权限原则
- Token 保护: 客户端应妥善保护 Token,避免泄露
- 定期更新: 建议用户定期更改密码,特别是涉及敏感操作的用户
- 多重验证: 对于关键操作,建议实现多重验证机制
- 异常监控: 建立完善的异常日志和监控机制,及时发现和处理安全问题
- 性能优化: 优化认证和会话查询性能,减少数据库压力
13. 未来优化方向
- 支持更多登录方式: 如手机号验证码登录、第三方社交账号登录等
- 双因素认证: 增加短信、邮箱验证码等双因素认证机制
- 单点登录: 实现多应用间的单点登录功能
- 会话管理可视化: 提供用户会话管理的可视化界面
- 自适应认证: 根据风险评估动态调整认证强度
