文档目录
身份认证

简介

本文件面向 DouPHP 后台管理员的身份认证机制,覆盖登录验证流程、会话管理与状态恢复、中间件 AuthMiddleware 的工作原理(含 IP 绑定与异常处理)、会话安全策略(超时、并发控制、劫持防护)、登录失败锁定与审计日志记录,并提供多因素认证(短信验证码、邮箱验证、第三方认证)的集成建议。

项目结构

DouPHP 后台认证由“路由 → 控制器 → 编排服务 → Guard → 模型/存储”的分层组成,并通过中间件链完成鉴权、权限校验、CSRF 保护与会话上下文注入。

graph TB
Client["浏览器"] --> Router["路由 admin/route/login.php"]
Router --> Ctl["控制器 LoginController"]
Ctl --> Flow["编排 AdminLoginFlow"]
Flow --> Guard["Guard AuthService"]
Guard --> Model["模型 Manager"]
Guard --> Session["Session/Store"]
Client --> MW_Auth["中间件 AuthMiddleware"]
MW_Auth --> MW_Permission["中间件 PermissionMiddleware"]
MW_Permission --> MW_Workspace["中间件 AdminWorkspaceMiddleware"]
MW_Workspace --> Controller["业务控制器"]
Client --> CSRF["中间件 CsrfMiddleware"]

核心组件

  • 路由与豁免:登录相关路由显式豁免 auth/permission/workspace/csrf,避免未登录死循环。
  • 控制器:负责表单校验、调用编排服务、统一消息返回。
  • 编排服务:串联验证码、输入校验、IP 限流、账号锁定检测、凭据校验、登录后副作用(CSRF token、缓存清理、审计、事件)。
  • Guard:实现凭据校验、会话写入、remember-me、会话恢复、失败计数与锁定。
  • 模型:持久化管理员信息、登录失败计数、锁定时间、最近登录信息与 remember token。
  • 中间件链:AuthMiddleware(恢复会话)、PermissionMiddleware(模块权限)、AdminWorkspaceMiddleware(视图变量注入)、CsrfMiddleware(表单令牌校验)。

架构总览

后台管理员登录与访问的整体时序如下:

sequenceDiagram
participant B as "浏览器"
participant R as "路由"
participant M as "中间件链"
participant C as "控制器"
participant F as "编排服务"
participant G as "Guard"
participant DB as "数据库/会话"
B->>R : GET /admin/login
R-->>B : 登录页(豁免中间件)
B->>R : POST /admin/login/post
R-->>C : 控制器 post()
C->>F : handle(data, ip)
F->>G : attempt(credentials, remember, ip)
G->>DB : 查询管理员/校验密码/记录失败或成功
G->>DB : 写入 session/admin_id/shell/ontime
G-->>F : true/false
F->>F : 成功后生成 static_admin 令牌/清理缓存/写审计/触发事件
F-->>C : 抛出重定向
C-->>B : 跳转后台首页
Note over M,B : 后续请求进入中间件链
B->>M : 任意受保护页面
M->>G : restoreFromSession(ip)
G-->>M : 已登录则放行,否则重定向登录页

详细组件分析

后台管理员登录验证流程

  • 入口:POST /admin/login/post,路由级豁免 auth/permission/workspace/csrf,避免匿名提交 CSRF 失败。
  • 控制器:接收并校验表单数据,调用编排服务处理登录。
  • 编排服务:
    • 可选验证码校验(site.captcha 开启时)。
    • 用户名格式校验与审计。
    • IP 限流检查(基于 admin_log 中 LOGIN_FAIL 计数)。
    • 调用 Guard.attempt 进行凭据校验与登录态写入。
    • 成功后生成静态 CSRF 令牌、清理模板缓存、写审计日志、触发系统事件并重定向到后台首页。
  • Guard.attempt:
    • 参数清洗与空值判断。
    • IP 限流判定。
    • 按用户名查找管理员,若存在且未锁定,则校验密码(兼容历史 md5 自动升级为 bcrypt)。
    • 失败记录登录失败次数,达到阈值后设置锁定时间。
    • 成功后调用 login 写入会话、更新最近登录信息、发放 remember-me 凭证(可选),并注入当前用户上下文。
flowchart TD
Start(["开始"]) --> Validate["表单校验/用户名格式校验"]
Validate --> Captcha{"启用验证码?"}
Captcha --> |是| CheckCaptcha["验证码校验"]
Captcha --> |否| RateLimit["IP 限流检查"]
CheckCaptcha --> RateLimit
RateLimit --> Attempt{"尝试登录"}
Attempt --> |失败| HandleFail["记录失败/锁定/审计/提示"]
Attempt --> |成功| PostLogin["生成CSRF令牌/清理缓存/审计/事件/重定向"]
HandleFail --> End(["结束"])
PostLogin --> End

会话管理与状态恢复机制

  • 登录写入:
    • 会话 ID 再生,防止会话固定攻击。
    • 写入 admin_id、shell(基于用户名+密码+全局密钥的哈希)、ontime(心跳时间戳)。
    • 重置登录失败状态,更新最近登录时间与 IP。
    • 可选发放 remember-me 令牌(Cookie + 数据库 token 哈希 + 过期时间)。
  • 会话恢复:
    • 优先尝试通过 remember-me Cookie 自动续登,补发 CSRF 静态令牌,确保后续 POST 不触发非法操作。
    • 从 Session 读取 admin_id 与 shell,结合数据库管理员行校验 shell,通过后刷新心跳时间戳并注入上下文。
  • 会话超时:
    • 每次恢复或登录后刷新 ontime;当超过配置超时阈值时清空会话,强制重新登录。
  • 登出:
    • 清空会话、删除 remember-me Cookie、重置实例状态。
classDiagram
class AuthService {
+attempt(credentials, remember, ip) bool
+login(user, remember, ip) void
+logout() void
+restoreFromSession(ip) array|null
+id() int
+user() array
+check() bool
+guest() bool
-buildAdminPayload(admin) array
-findBySession(adminId, shell) array|null
-touchSession(timeout) void
-tryRememberLogin(ip) void
-verifyPassword(input, user) bool
-recordLoginFail(adminId) void
-issueRememberToken(adminId) void
}
class Manager {
+updateLastLogin(id, ip, time) bool
+updateRememberToken(id, hash, expire) bool
+countLoginFailuresByIp(ip, since) int
+getLoginLockTime(id) int
+updateLoginFailState(id, count, lockTime) bool
+resetLoginFailState(id) bool
}
AuthService --> Manager : "读写管理员状态/失败计数/锁定/最近登录"

AuthMiddleware 工作原理(session 恢复、IP 绑定、异常处理)

  • 职责单一:仅负责恢复登录态。通过 auth('admin')->restoreFromSession(request()->ip()) 将客户端 IP 作为续登时的 last_ip 更新依据。
  • 未登录处理:若恢复失败,抛出 HttpResponseException 并重定向到登录路由。
  • 免登声明:登录页与验证码等入口通过路由级 withoutMiddleware 豁免,不在中间件内硬编码白名单。
  • 后续链路:通过后再交由 PermissionMiddleware 与 AdminWorkspaceMiddleware 做权限与视图变量注入。
sequenceDiagram
participant Req as "请求"
participant MW as "AuthMiddleware"
participant G as "Guard"
participant R as "路由"
Req->>MW : handle(next)
MW->>G : restoreFromSession(ip)
alt 已登录
G-->>MW : payload
MW-->>Req : next()
else 未登录
MW-->>Req : 抛出异常 -> 重定向到登录页
end

权限与工作台注入

  • 权限中间件:在 AuthMiddleware 之后执行,检查当前管理员对目标模块/动作的访问权限;超级管理员直接放行,受限管理员按 action_list 白名单判定。
  • 工作台中间件:在权限通过后向视图注入 global_admin、workspace、unum 等变量,供布局模板使用。

CSRF 与表单安全

  • 后台统一使用静态令牌 static_admin,登录成功后生成,各表单渲染时携带并提交,由 CsrfMiddleware 自动校验。
  • 找回密码提交使用一次性令牌 password_reset,由路由映射决定。
  • 完全豁免 csrf 的路由(如登录提交、安装 JSON API)通过路由级 withoutMiddleware 声明,避免未登录场景下的令牌缺失问题。

依赖关系分析

  • 控制器依赖编排服务,编排服务依赖 Guard、缓存清理、验证码、审计与事件。
  • Guard 依赖模型与 Session/Store,模型负责数据库持久化。
  • 中间件链顺序:AuthMiddleware → PermissionMiddleware → AdminWorkspaceMiddleware;CSRF 中间件作用于所有需要保护的 POST/GET 端点。
  • 配置项 security.session 影响会话 Cookie 的安全属性(httponly、secure、samesite、use_strict_mode)。
graph LR
Ctl["LoginController"] --> Flow["AdminLoginFlow"]
Flow --> Guard["AuthService"]
Flow --> Cache["CacheClearService"]
Flow --> Captcha["Captcha"]
Flow --> Audit["AuditService"]
Flow --> Event["Event"]
Guard --> Model["Manager"]
Guard --> Session["Session/Store"]
MW_A["AuthMiddleware"] --> Guard
MW_P["PermissionMiddleware"] --> Gate["AdminGate"]
MW_W["AdminWorkspaceMiddleware"] --> View["DouView"]
CSRF["CsrfMiddleware"] --> Config["security.session"]

性能与安全考量

  • 会话超时:通过 ontime 心跳与 touchSession 控制,默认超时为 7 天(604800 秒),超时会话将被清空。
  • 并发控制:
    • 登录失败按 IP 限流(窗口期与阈值可配置),避免暴力破解。
    • 账号锁定:连续失败达到阈值后锁定一段时间(例如 15 分钟),期间拒绝登录。
  • 会话劫持防护:
    • 登录时会话 ID 再生,降低会话固定风险。
    • Shell 校验:基于用户名+密码+全局密钥的哈希,配合数据库管理员行比对,增强会话有效性。
    • Remember-me:使用随机令牌哈希与过期时间,过期自动失效。
    • CSRF:静态令牌与一次性令牌结合,防止跨站请求伪造。
    • 安全响应头与可信代理/Host:通过 security 配置下发安全头与信任策略,减少 Host 头注入与代理误判。
  • 审计日志:登录成功/失败均记录审计日志,包含 IP、用户名、失败原因标签等,便于追踪与分析。

故障排查指南

  • 无法登录:
    • 检查是否命中 IP 限流或账号锁定;查看审计日志中的失败原因标签(IP_RATE_LIMITED、ACCOUNT_LOCKED、INPUT_WRONG)。
    • 确认验证码是否开启且正确;验证码错误会记录 CAPTCHA_WRONG。
  • 登录后仍被重定向到登录页:
    • 检查会话是否被 GC 回收;remember-me 会自动续登并补发 CSRF 静态令牌。
    • 确认 CSRF 令牌是否正确生成与提交;登录成功后会生成 static_admin。
  • 越权访问:
    • 检查权限中间件判定逻辑与 action_list 白名单;无权限会被重定向到后台首页。
  • 审计日志位置:
    • 登录失败/成功均通过审计服务写入,可通过审计接口或日志工具检索。

结论

DouPHP 后台认证采用分层设计:路由豁免登录入口、控制器负责表单校验、编排服务串联安全策略、Guard 管理凭据与会话、模型持久化状态、中间件链保障鉴权与 CSRF。整体具备完善的会话恢复、IP 限流、账号锁定、审计日志与安全响应头配置,满足企业级后台的安全需求。

附录:多因素认证集成方案

以下方案为扩展建议,需在不破坏现有登录编排的前提下以插件或服务方式接入。

  • 短信验证码(SMS OTP)

    • 在 AdminLoginFlow.handle 中增加“二次验证”步骤:首次凭据校验通过后,要求输入短信验证码;验证码校验通过后再执行 postLoginActions。
    • 验证码发送与校验可复用前端短信能力,并在后端加入频率限制与一次性消费。
    • 审计:记录 SMS 发送与校验结果,区分成功/失败原因。
  • 邮箱验证(Email OTP)

    • 在登录成功后或敏感操作前触发邮箱验证码;校验通过后方可继续。
    • 邮件内容包含一次性链接或验证码,服务端校验后标记为已使用。
    • 审计:记录邮箱发送与校验结果。
  • 第三方认证服务(OAuth/OIDC)

    • 在登录流程中增加“第三方授权”入口;回调后获取用户标识并与本地管理员账户关联。
    • 支持绑定多账户与解绑;失败时记录审计日志。
    • 会话:第三方认证成功后可复用现有会话写入逻辑,或签发短期令牌用于无状态场景。
  • 集成要点

    • 编排:在 AdminLoginFlow 中插入“多因素校验”阶段,保持凭据校验与会话写入分离。
    • 安全:对所有二次验证步骤实施速率限制与一次性消费;记录审计日志。
    • 配置:通过配置开关控制是否启用多因素认证及具体通道(短信/邮箱/第三方)。
添加日期:2026-10-05