用户认证流程
完整调用链路
sequenceDiagram
participant User as 用户
participant Frontend as 前端 (React)
participant API as API 客户端
participant Backend as 后端 (Express)
participant LoginLimit as 登录限制服务
participant Adapter as 业务适配器层
participant DB as 数据库
participant TOTP as TOTP 服务
participant Audit as 审计服务
User->>Frontend: 1. 输入用户名/密码
Frontend->>API: 2. 调用 authApi.login()
API->>Backend: 3. POST /api/auth/login
Backend->>LoginLimit: 4. checkLoginAllowed()
LoginLimit->>Adapter: 5. get() 查询登录限制配置
Adapter->>DB: 6. SELECT * FROM system_settings
DB-->>Adapter: 返回配置
Adapter-->>LoginLimit: 返回配置
LoginLimit->>Adapter: 7. get() 查询失败尝试记录
Adapter->>DB: 8. SELECT * FROM login_attempts
DB-->>Adapter: 返回记录
Adapter-->>LoginLimit: 返回记录
LoginLimit-->>Backend: 9. 返回是否允许登录
alt 登录被限制
Backend-->>API: 返回错误:账户被锁定
API-->>Frontend: 显示错误信息
Frontend-->>User: 提示稍后重试
else 允许登录
Backend->>Adapter: 10. get() 查询用户信息
Adapter->>DB: 11. SELECT * FROM users WHERE ...
DB-->>Adapter: 返回用户数据
Adapter-->>Backend: 返回用户数据
alt 用户不存在
Backend->>LoginLimit: 记录失败尝试
Backend-->>API: 返回:用户名或密码错误
else 用户存在
Backend->>Backend: bcrypt.compare 密码
alt 密码错误
Backend->>LoginLimit: 记录失败尝试
Backend-->>API: 返回:密码错误
else 密码正确
Backend->>TOTP: 检查 2FA 状态
TOTP-->>Backend: 返回是否启用
alt 2FA 已启用
Backend-->>API: 返回 code: -2 (需要 2FA)
API-->>Frontend: 显示 2FA 输入框
User->>Frontend: 输入 2FA 码
Frontend->>API: 重新调用 login (带 totpCode)
API->>Backend: POST /api/auth/login
Backend->>TOTP: verifyTOTPToken()
end
Backend->>LoginLimit: clearLoginAttempts()
Backend->>Audit: logAuditOperation()
Backend->>Backend: signToken() 生成 JWT
Backend-->>API: 返回:{token, user}
API-->>Frontend: 存储 token
Frontend-->>User: 跳转到 Dashboard
end
end
end
关键代码路径
前端调用链
Login.tsx
→ authApi.login()
→ api.post('/auth/login')
→ Axios 拦截器 (添加 Token)
后端处理链
POST /api/auth/login (routes/auth.ts)
→ loginLimiter 中间件 (限流)
→ checkLoginAllowed() (service/loginLimit.ts)
→ get() 查询用户 (通过业务适配器层)
→ bcrypt.compareSync() 验证密码
→ getTOTPStatus() 检查 2FA (service/totp.ts)
→ verifyTOTPToken() 验证 2FA 码
→ clearLoginAttempts() 清除记录 (service/loginLimit.ts)
→ signToken() 生成 JWT (middleware/auth.ts)
→ logAuditOperation() 记录审计 (service/audit.ts)
→ 返回 {token, user}
数据流
用户输入
↓
前端表单验证
↓
authApi.login(username, password)
↓
POST /api/auth/login
↓
[后端] loginLimiter 中间件
↓
[后端] checkLoginAllowed() - 检查登录限制
↓
[后端] get() - 查询用户 (通过业务适配器层)
↓
[后端] bcrypt.compare() - 验证密码
↓
[后端] getTOTPStatus() - 检查 2FA
↓
[后端] verifyTOTPToken() - 验证 2FA 码 (如果需要)
↓
[后端] clearLoginAttempts() - 清除失败记录
↓
[后端] signToken() - 生成 JWT
↓
[后端] logAuditOperation() - 记录审计日志
↓
返回 {token, user}
↓
前端存储 token 到 localStorage
↓
更新 AuthContext
↓
重定向到 Dashboard