简介
本技术文档面向 DouPHP 用户认证系统的开发者,围绕管理员登录、会员注册/登录、密码重置、会话管理、多端登录(Web/小程序/API)、安全令牌与验证码等关键能力进行系统化说明。文档从架构到实现细节逐层展开,并提供流程图、时序图与类图帮助理解数据流与控制流;同时给出扩展认证方式、自定义验证规则、第三方登录集成的最佳实践建议。
更新 本次更新重点增强了密码验证机制,支持历史MD5密码格式的无缝迁移到现代bcrypt算法,同时改进了开发者合作伙伴的判定逻辑,提升了系统的安全性和兼容性。
项目结构
认证相关代码按"端"划分:后台(admin)、前端(front)、API(api),并通过统一的认证管理器 AuthManager 提供多 Guard 解析。后台登录流程由控制器、编排服务、认证 Guard、中间件协同完成;密码重置由独立服务处理;API 端通过中间件从请求头提取 token 并注入上下文;小程序侧维护本地登录态并与后端交互。
graph TB
subgraph "后台"
A["登录控制器<br/>LoginController"]
B["登录编排服务<br/>AdminLoginFlow"]
C["认证守卫<br/>AuthService"]
D["认证中间件<br/>AuthMiddleware"]
end
subgraph "前端"
E["前端认证<br/>Front Auth"]
F["密码升级机制<br/>MD5→bcrypt"]
end
subgraph "API"
G["API 认证中间件<br/>UserAuthMiddleware"]
end
subgraph "小程序"
H["认证状态存储<br/>auth.ts"]
end
I["认证管理器<br/>AuthManager"]
J["合作伙伴判定<br/>Cdkey"]
A --> B --> C
D --> C
E --> F
G --> I
H --> G
J --> I
图表来源
- admin/controller/login/LoginController.php:61-151
- admin/service/login/AdminLoginFlow.php:67-128
- admin/service/auth/AuthService.php:119-181
- front/facade/Auth.php:612-633
- core/support/Cdkey.php:39-56
章节来源
- admin/controller/login/LoginController.php:61-151
- admin/service/login/AdminLoginFlow.php:67-128
- admin/service/auth/AuthService.php:119-181
- front/facade/Auth.php:612-633
- core/support/Cdkey.php:39-56
核心组件
- 认证管理器(AuthManager):统一注册与解析各端 Guard(admin/front/api),强制显式指定 guard 名,避免默认 guard 歧义。
- 后台认证守卫(AuthService):实现 StatefulGuardContract,负责凭据校验、登录态写入、remember-me、IP 限流、账号锁定、密码升级等。
- 前端认证(Front Auth):支持MD5和bcrypt双格式密码验证,自动升级历史MD5密码到bcrypt。
- 登录编排服务(AdminLoginFlow):串联验证码、输入校验、IP 限流、账号锁定检测、调用 guard.attempt、登录后副作用(CSRF、缓存清理、审计、事件)。
- 密码重置服务(PasswordResetService):独立于登录态,负责发起重置邮件、校验重置令牌、完成新密码设置。
- 合作伙伴判定(Cdkey):增强开发者合作伙伴身份识别逻辑,支持多种授权格式。
- 中间件:
- 后台 AuthMiddleware:恢复会话登录态,未登录跳转登录页。
- API UserAuthMiddleware:从 Authorization 头提取 token,解析上下文并注入 auth('api')。
- 小程序认证状态:本地持久化 token 与登录标志,支持恢复与确保登录。
章节来源
- core/foundation/auth/AuthManager.php:40-114
- admin/service/auth/AuthService.php:119-181
- front/facade/Auth.php:612-633
- admin/service/login/AdminLoginFlow.php:67-128
- admin/service/login/PasswordResetService.php:47-95
- core/support/Cdkey.php:39-56
架构总览
认证体系采用"多 Guard + 中间件 + 编排服务"的分层设计:
- 控制器仅负责接收请求与响应,不承载复杂业务。
- 编排服务负责跨步骤的流程控制与副作用。
- Guard 专注凭据校验与登录态写入。
- 中间件在 HTTP 边界做鉴权与上下文注入。
- 小程序端维护本地登录态,配合 API 中间件完成无状态鉴权。
更新 新增了对历史MD5密码格式的兼容支持,实现了平滑的密码算法升级机制。
sequenceDiagram
participant U as "管理员"
participant C as "登录控制器"
participant F as "登录编排服务"
participant G as "认证守卫"
participant M as "认证中间件"
U->>C : 提交用户名/密码/验证码
C->>F : handle(表单数据, IP)
F->>F : 验证码校验 / 输入格式校验
F->>G : attempt(凭据, remember, IP)
G->>G : verifyPassword(MD5/bcrypt)
G-->>F : true/false
alt 成功
F->>F : 生成 CSRF / 清理缓存 / 审计 / 事件
F-->>C : 抛出重定向异常
C-->>U : 跳转到后台首页
else 失败
F-->>C : 抛出域异常提示文案
C-->>U : 返回登录页并显示错误
end
Note over M,U : 访问受保护页面时,中间件恢复会话或拒绝访问
图表来源
- admin/controller/login/LoginController.php:75-117
- admin/service/login/AdminLoginFlow.php:77-117
- admin/service/auth/AuthService.php:119-155
- admin/service/auth/AuthService.php:412-425
详细组件分析
后台登录流程(控制器 → 编排服务 → 守卫)
- 控制器接收登录表单,委托编排服务处理。
- 编排服务依次执行:验证码校验、用户名格式校验、IP 限流检查、调用守卫 attempt。
- 守卫内部:查找用户、检查锁定、校验密码(兼容历史 md5 并升级为 bcrypt)、记录失败次数、必要时锁定账号、成功后写入 Session/Remember Token 并更新最后登录信息。
- 成功后编排服务触发 CSRF 令牌生成、缓存清理、审计日志、系统事件,并重定向至后台首页。
更新 密码验证现在支持MD5和bcrypt双格式,自动检测并升级历史MD5密码。
flowchart TD
Start(["开始"]) --> Captcha["验证码校验"]
Captcha --> Valid{"验证码有效?"}
Valid -- 否 --> FailCaptcha["记录失败并返回错误"]
Valid -- 是 --> CheckFormat["用户名格式校验"]
CheckFormat --> FormatOK{"格式合法?"}
FormatOK -- 否 --> FailFormat["记录失败并返回错误"]
FormatOK -- 是 --> RateLimit["IP 限流检查"]
RateLimit --> LimitOK{"未超限?"}
LimitOK -- 否 --> FailRate["记录失败并返回错误"]
LimitOK -- 是 --> Attempt["守卫尝试登录"]
Attempt --> PasswordCheck["密码验证(MD5/bcrypt)"]
PasswordCheck --> Ok{"登录成功?"}
Ok -- 否 --> FailAuth["记录失败并返回错误"]
Ok -- 是 --> PostActions["生成CSRF/清理缓存/审计/事件"]
PostActions --> Redirect["重定向到后台首页"]
FailCaptcha --> End(["结束"])
FailFormat --> End
FailRate --> End
FailAuth --> End
Redirect --> End
图表来源
- admin/service/login/AdminLoginFlow.php:77-117
- admin/service/auth/AuthService.php:119-155
- admin/service/auth/AuthService.php:412-425
章节来源
- admin/controller/login/LoginController.php:75-117
- admin/service/login/AdminLoginFlow.php:77-117
- admin/service/auth/AuthService.php:119-155
- admin/service/auth/AuthService.php:412-425
会话管理与多端登录
- 后台会话:
- 登录时生成新的 session ID,写入 admin_id、shell、ontime。
- 可选发放 remember-me Cookie,有效期 30 天;下次请求可自动续登并补发 CSRF 静态令牌。
- 会话心跳超时则清空会话。
- API 会话:
- 通过 Authorization: Bearer <token> 传递 token。
- 中间件从请求头提取 token,调用 auth('api')->resolveUserContext 解析上下文并注入。
- 未认证返回 401,无工作身份返回 403。
- 小程序会话:
- 本地存储 api_token、user_id、loginEd。
- 启动时恢复登录态,若接口返回 UNAUTHORIZED 则清空本地登录标志。
更新 增强了合作伙伴判定逻辑,支持更灵活的授权格式。
classDiagram
class AuthService {
+id() int
+user() array
+check() bool
+guest() bool
+attempt(credentials, remember, ip) bool
+login(user, remember, ip) void
+logout() void
+restoreFromSession(ip) array|null
+ipRateLimited(ip, limit, window) bool
+isLocked(adminId) bool
+lockSecondsRemaining(adminId) int
+verifyPassword(password, user) bool
}
class FrontAuth {
+verifyPassword(password, user) bool
+upgradeToBcrypt(userId, password) void
}
class Cdkey {
+read(file) array
+parsePartnerFlag(content) bool
}
class AdminLoginFlow {
+handle(data, ip) void
+logout() void
}
AdminLoginFlow --> AuthService : "调用"
AuthService --> FrontAuth : "密码验证"
Cdkey --> AuthService : "合作伙伴判定"
图表来源
- admin/service/auth/AuthService.php:64-181
- front/facade/Auth.php:612-633
- core/support/Cdkey.php:39-56
章节来源
- admin/service/auth/AuthService.php:165-193
- admin/service/auth/AuthService.php:208-227
- admin/service/auth/AuthService.php:376-403
- front/facade/Auth.php:612-633
- core/support/Cdkey.php:39-56
密码重置流程
- 发起重置:校验用户名与邮箱,生成随机重置令牌并保存哈希值与过期时间,发送邮件包含带 uid/code 的重置链接。
- 重置落地:校验 uid/code 是否匹配且未过期,校验新密码及确认密码,完成后写入 bcrypt 哈希并清除重置令牌。
- 控制器负责渲染表单与处理 POST 提交,服务负责业务逻辑。
sequenceDiagram
participant U as "管理员"
participant C as "登录控制器"
participant S as "密码重置服务"
participant M as "邮件服务"
U->>C : 打开找回密码页面
C->>S : buildPasswordResetData(uid, code)
alt 有有效令牌
C-->>U : 展示重置密码表单
U->>C : 提交新密码
C->>S : passwordResetPost(data)
S->>S : validatePasswordResetToken
S->>S : 写入新密码(bcrypt)
S-->>C : 返回成功消息
C-->>U : 跳转登录页
else 无令牌或无效
C-->>U : 展示发起重置表单
U->>C : 提交用户名+邮箱
C->>S : passwordResetPost(data)
S->>M : 发送重置邮件
S-->>C : 返回已发送邮件地址
C-->>U : 提示查看邮箱
end
图表来源
- admin/controller/login/LoginController.php:101-151
- admin/service/login/PasswordResetService.php:47-95
- admin/service/login/PasswordResetService.php:132-185
- admin/service/login/PasswordResetService.php:193-218
章节来源
- admin/controller/login/LoginController.php:101-151
- admin/service/login/PasswordResetService.php:47-95
- admin/service/login/PasswordResetService.php:132-185
- admin/service/login/PasswordResetService.php:193-218
安全策略与令牌处理
- 密码加密:
- 更新 登录时识别历史 md5 哈希并即时升级为 bcrypt,支持MD5和bcrypt双格式验证。
- 重置密码使用 bcrypt 哈希存储。
- 验证码:
- 登录前根据配置启用验证码校验,失败记录审计日志并返回错误。
- 登录失败锁定:
- 连续失败达到阈值后锁定账号一段时间,期间拒绝登录。
- IP 级限流防止暴力破解。
- Remember-me:
- 登录时可发放长期 Cookie,下次请求自动续登并补发 CSRF 静态令牌。
- API 鉴权:
- 通过 Authorization 头携带 token,中间件解析并注入上下文,未认证返回 401,无工作身份返回 403。
- 更新 合作伙伴判定:
- 增强的Cdkey解析器支持多种授权格式,包括十进制和十六进制编码。
- 改进的$_PARTNER_AUTHORIZED标记解析逻辑。
章节来源
- admin/service/auth/AuthService.php:412-425
- front/facade/Auth.php:612-633
- admin/service/login/AdminLoginFlow.php:144-156
- admin/service/auth/AuthService.php:275-303
- admin/service/auth/AuthService.php:446-459
- core/support/Cdkey.php:88-103
认证中间件与权限检查
- 后台 AuthMiddleware:
- 恢复会话登录态,未登录抛异常跳转登录页。
- 免登入口通过路由豁免中间件。
- API UserAuthMiddleware:
- 从请求头提取 token,调用 auth('api')->resolveUserContext 解析上下文并注入。
- 未认证返回 401,无工作身份返回 403。
- 权限检查:
- 菜单与权限判定不在认证守卫内,由授权模块负责(如 AdminGate)。
章节来源
- admin/middleware/AuthMiddleware.php:36-50
- api/middleware/UserAuthMiddleware.php:47-64
- api/middleware/UserAuthMiddleware.php:69-92
依赖关系分析
- 控制器依赖编排服务与表单请求对象。
- 编排服务依赖认证守卫、验证码、缓存清理、审计、事件。
- 认证守卫依赖数据库、会话、模型、配置。
- 中间件依赖认证管理器与请求对象。
- 小程序依赖本地存储与网络请求。
更新 新增了前端认证对密码升级的支持,以及合作伙伴判定对授权文件的依赖。
graph LR
LC["登录控制器"] --> ALF["登录编排服务"]
ALF --> AS["认证守卫"]
ALF --> CAP["验证码"]
ALF --> AUD["审计日志"]
AS --> DB["数据库"]
AS --> SES["会话"]
FA["前端认证"] --> PB["密码升级"]
PB --> DB
AMW["后台中间件"] --> AS
UAM["API中间件"] --> AUTHM["认证管理器"]
MP["小程序认证"] --> UAM
CK["合作伙伴判定"] --> AUTHM
图表来源
- admin/controller/login/LoginController.php:75-117
- admin/service/login/AdminLoginFlow.php:67-128
- admin/service/auth/AuthService.php:119-181
- front/facade/Auth.php:612-633
- core/support/Cdkey.php:39-56
章节来源
- admin/controller/login/LoginController.php:75-117
- admin/service/login/AdminLoginFlow.php:67-128
- admin/service/auth/AuthService.php:119-181
- front/facade/Auth.php:612-633
- core/support/Cdkey.php:39-56
性能与安全考量
- 性能:
- 登录成功后清理模板缓存,避免频繁重建。
- 会话心跳机制减少无效会话占用。
- API 中间件无状态鉴权,适合水平扩展。
- 更新 密码升级采用惰性策略,仅在用户登录时升级,避免批量迁移的性能开销。
- 安全:
- 更新 密码哈希升级与 bcrypt 存储,支持MD5到bcrypt的平滑迁移。
- 验证码与 IP 限流抵御暴力破解。
- 账号锁定限制恶意尝试。
- Remember-me 令牌短期有效且服务端哈希比对。
- API 使用 Bearer Token,未认证/无权限明确返回错误码。
- 更新 增强的合作伙伴授权验证,支持多种授权格式。
故障排查指南
- 登录失败:
- 检查验证码是否开启且正确。
- 检查 IP 是否被限流。
- 检查账号是否被锁定。
- 检查用户名/密码是否正确。
- 更新 检查密码格式是否为MD5或bcrypt,确认密码升级逻辑是否正常。
- 密码重置失败:
- 检查重置链接是否过期。
- 检查邮箱与用户名是否匹配。
- 检查邮件发送是否成功。
- API 未认证:
- 检查 Authorization 头是否携带有效 token。
- 检查 token 是否过期或被撤销。
- 小程序假登出:
- 检查网络错误是否为 UNAUTHORIZED。
- 检查本地存储的 api_token 是否有效。
- 更新 合作伙伴功能异常:
- 检查授权文件是否存在且格式正确。
- 检查$_PARTNER_AUTHORIZED标记是否被正确解析。
章节来源
- admin/service/login/AdminLoginFlow.php:166-201
- admin/service/login/PasswordResetService.php:132-185
- api/middleware/UserAuthMiddleware.php:77-92
- front/facade/Auth.php:612-633
- core/support/Cdkey.php:88-103
结论
DouPHP 认证系统通过清晰的分层与职责分离,实现了安全的后台登录、灵活的密码重置、稳定的会话管理与多端鉴权。其设计便于扩展新的认证方式与第三方集成,同时提供了完善的安全策略与可观测性(审计日志与事件)。
更新 本次增强特别关注了密码安全的现代化升级,通过支持MD5和bcrypt双格式,实现了向后兼容的同时提升了安全性。增强的合作伙伴判定逻辑也为系统授权提供了更灵活的解决方案。开发者可基于现有组件快速构建符合业务需求的认证流程。
附录:扩展与集成实践
- 扩展认证方式:
- 新增前端或 API 的 Guard 实现,并在 Init 阶段通过 AuthManager::extend 注册。
- 在对应端的中间件中解析凭证并注入上下文。
- 添加自定义验证规则:
- 在编排服务中插入自定义校验步骤,失败时抛出域异常并记录审计日志。
- 第三方登录集成:
- 在登录编排服务中接入第三方回调,验证成功后调用守卫.login 直接写入登录态。
- 注意同步更新最后登录信息与刷新会话。
- 使用认证中间件:
- 后台路由通过中间件恢复会话,未登录跳转登录页。
- API 路由通过中间件解析 token,未认证返回 401。
- 权限检查机制:
- 在权限中间件中依据用户角色与工作身份进行资源访问控制。
- 用户状态管理:
- 通过守卫.user() 获取当前主体资料,结合事件与审计记录用户行为。
- 更新 密码格式迁移:
- 系统自动检测MD5格式密码并在登录时升级到bcrypt。
- 无需手动干预,用户体验无缝。
- 更新 合作伙伴授权:
- 支持多种授权文件格式,包括十进制和十六进制编码。
- 增强的$_PARTNER_AUTHORIZED标记解析逻辑。
章节来源
- core/foundation/auth/AuthManager.php:58-67
- admin/service/login/AdminLoginFlow.php:77-117
- admin/service/auth/AuthService.php:165-181
- front/facade/Auth.php:612-633
- admin/middleware/AuthMiddleware.php:42-50
- api/middleware/UserAuthMiddleware.php:47-64
- core/support/Cdkey.php:39-56