文档目录
身份验证中间件

简介

本技术文档聚焦 DouPHP 后台的身份验证与权限控制中间件,围绕 AuthMiddleware(认证)与 PermissionMiddleware(权限)展开,解释请求拦截机制、会话恢复流程、令牌检查逻辑、登录态检测、权限判定规则、动态权限分配等关键实现。同时给出执行顺序、错误处理策略、性能优化建议,以及常见问题与解决方案,帮助开发者安全地扩展中间件能力并实现细粒度权限控制。

项目结构

后台入口通过路由调度器将请求交由中间件管道处理,认证与权限作为前置中间件在控制器之前执行;工作台变量注入中间件位于认证与权限之后,确保仅在已认证的上下文中注入视图变量。

graph TB
A["请求进入<br/>admin/index.php"] --> B["路由解析<br/>AdminResolver"]
B --> C["调度执行<br/>Dispatcher.run()"]
C --> D["中间件管道"]
D --> E["认证中间件<br/>AuthMiddleware"]
E --> F["权限中间件<br/>PermissionMiddleware"]
F --> G["工作台变量注入<br/>AdminWorkspaceMiddleware"]
G --> H["控制器动作"]

核心组件

  • 认证中间件(AuthMiddleware)
    • 职责:从会话恢复管理员登录态;未登录则重定向到登录页。
    • 关键点:使用 auth('admin')->restoreFromSession(ip) 进行会话恢复;失败时抛出响应异常以短路返回。
  • 权限中间件(PermissionMiddleware)
    • 职责:校验当前管理员对目标模块/动作的访问权限;超级管理员直接放行;普通管理员按白名单判定。
    • 关键点:读取 routeModule/routeAction/id,调用 AdminGate::canAccess 进行授权判定。
  • 工作台变量注入中间件(AdminWorkspaceMiddleware)
    • 职责:为模板注入全局管理员信息、工作区数据与更新角标;仅在认证通过后注入。
  • 路由调度器(Router)
    • 职责:解析路由计划并交由 Dispatcher 在中间件管道中执行;未匹配或方法不允许时重定向首页并提示。
  • 中间件接口(MiddlewareInterface)
    • 职责:定义 handle($next) 契约;要求中间件必须 return $next() 以冒泡下层响应。

架构总览

后台请求的生命周期如下:

  • 路由层解析出 DispatchPlan,交由中央调度器运行中间件管道。
  • 认证中间件优先执行,负责会话恢复与登录态校验。
  • 权限中间件随后执行,依据角色与白名单进行模块级访问控制。
  • 工作台中间件最后注入视图所需上下文。
  • 最终进入控制器业务逻辑。
sequenceDiagram
participant Client as "客户端"
participant Router as "路由调度器"
participant Pipe as "中间件管道"
participant Auth as "认证中间件"
participant Perm as "权限中间件"
participant Work as "工作台中间件"
participant Ctrl as "控制器"
Client->>Router : 发起后台请求
Router->>Pipe : 构建并运行管道
Pipe->>Auth : handle(next)
Auth-->>Pipe : 未登录 -> 重定向登录页
Auth-->>Pipe : 已登录 -> 继续 next()
Pipe->>Perm : handle(next)
Perm-->>Pipe : 无权限 -> 重定向首页
Perm-->>Pipe : 有权限 -> 继续 next()
Pipe->>Work : handle(next)
Work-->>Pipe : 注入 global_admin/workspace/unum
Pipe->>Ctrl : 执行业务逻辑
Ctrl-->>Client : 返回响应

详细组件分析

认证中间件(AuthMiddleware)

  • 请求拦截机制
    • 从会话恢复管理员登录态,携带客户端 IP 用于会话绑定校验。
    • 若恢复失败,立即抛出响应异常并重定向到登录路由。
  • 会话验证流程
    • 通过门面 auth('admin') 获取守卫实例,调用 restoreFromSession(ip)。
    • 成功时将管理员信息写入当前请求上下文,供后续中间件与控制器使用。
  • 令牌检查逻辑
    • 本中间件不直接校验 CSRF 令牌;CSRF 由独立中间件处理。
  • 错误处理
    • 未登录统一重定向到登录页,避免泄露内部状态。
  • 性能特性
    • 仅一次会话读取与判断,开销极低。
flowchart TD
Start(["进入认证中间件"]) --> Restore["从会话恢复管理员登录态<br/>auth('admin')->restoreFromSession(ip)"]
Restore --> Check{"是否恢复成功?"}
Check -- "否" --> Redirect["抛出响应异常并重定向到登录页"]
Check -- "是" --> Next["调用下一个中间件"]
Redirect --> End(["结束"])
Next --> End

权限中间件(PermissionMiddleware)

  • 权限验证规则
    • 读取当前管理员信息(需认证中间件已注入)。
    • 若为空,重定向登录页。
    • 读取当前模块与动作(默认 index),以及资源 id。
    • 调用 AdminGate::canAccess(admin, module, action, targetId) 判定。
    • 超级管理员(type 非 defined)直接放行;普通管理员按 action_list 白名单判定。
  • 动态权限分配
    • 通过 AdminGate 对外暴露 canAccess 接口,支持基于角色、模块、动作与资源 ID 的动态判定。
  • 错误处理
    • 无权限时重定向到后台首页,避免越权访问。
  • 执行顺序
    • 必须在认证中间件之后执行,确保 auth('admin')->user() 可用。
flowchart TD
Start(["进入权限中间件"]) --> GetAdmin["获取当前管理员信息"]
GetAdmin --> AdminCheck{"管理员存在?"}
AdminCheck -- "否" --> ToLogin["重定向到登录页"]
AdminCheck -- "是" --> ReadRoute["读取模块/动作/资源ID"]
ReadRoute --> GateCall["调用 AdminGate::canAccess(...)"]
GateCall --> Can{"是否允许访问?"}
Can -- "否" --> ToHome["重定向到后台首页"]
Can -- "是" --> Next["调用下一个中间件"]
ToLogin --> End(["结束"])
ToHome --> End
Next --> End

工作台变量注入中间件(AdminWorkspaceMiddleware)

  • 作用
    • 向模板注入 global_admin、workspace、unum 等视图变量。
  • 执行时机
    • 位于认证与权限之后,确保只有已认证且具备模块访问权的请求才会注入。
  • 健壮性
    • 若管理员上下文为空或视图引擎不可用,静默跳过,不影响后续处理。
flowchart TD
Start(["进入工作台中间件"]) --> HasAdmin{"是否存在管理员上下文?"}
HasAdmin -- "否" --> Next["直接放行"]
HasAdmin -- "是" --> Engine{"视图引擎可用?"}
Engine -- "否" --> Next
Engine -- "是" --> Inject["注入 global_admin / workspace / unum"]
Inject --> Next
Next --> End(["结束"])

路由调度器(Router)

  • 职责
    • 解析路由计划,处理“方法不允许”和“未找到”的情况,统一重定向至后台首页并附带提示信息。
    • 将计划交给 Dispatcher 在中间件管道中执行。
  • 与中间件的关系
    • 中间件在管道内执行,Router 负责整体编排与异常路径的重定向。
sequenceDiagram
participant R as "Router"
participant Res as "AdminResolver"
participant D as "Dispatcher"
R->>Res : resolve(request, container)
alt 方法不允许
R-->>R : 重定向首页并带错误提示
else 未找到
R-->>R : 重定向首页并带错误提示
else 正常
R->>D : run(plan, container)
D-->>R : 返回 Response 或 null
end

初始化与守卫注册(Init)

  • 启动流程
    • 设置常量、加载核心对象、注册 admin 认证守卫、装配视图引擎与模块。
  • 与认证的关系
    • 通过 AuthService 注册 auth('admin') 守卫,供中间件使用。
  • 其他
    • 计算 ROOT_URL 等站点常量,便于重定向与模板渲染。

依赖关系分析

  • 中间件之间耦合度低,遵循单一职责原则:
    • AuthMiddleware 只负责认证与会话恢复。
    • PermissionMiddleware 只负责权限判定。
    • AdminWorkspaceMiddleware 只负责视图变量注入。
  • 外部依赖
    • auth('admin') 守卫由 Init 注册。
    • AdminGate 提供权限判定能力。
    • Request 提供路由参数与元信息。
    • 响应异常 HttpResponseException 用于短路返回。
classDiagram
class MiddlewareInterface {
+handle(next) mixed
}
class AuthMiddleware {
+handle(next) mixed
}
class PermissionMiddleware {
-gate : AdminGate
+handle(next) mixed
}
class AdminWorkspaceMiddleware {
-workspaceBuilder : WorkspaceBuilder
-badgeBuilder : UpdateBadgeBuilder
+handle(next) mixed
}
class Router {
+dispatch() Response|null
}
AuthMiddleware ..|> MiddlewareInterface
PermissionMiddleware ..|> MiddlewareInterface
AdminWorkspaceMiddleware ..|> MiddlewareInterface
Router --> AuthMiddleware : "管道中使用"
Router --> PermissionMiddleware : "管道中使用"
Router --> AdminWorkspaceMiddleware : "管道中使用"

性能考虑

  • 最小化 I/O
    • 认证中间件仅进行一次会话读取与判断,避免重复查询。
  • 早短路
    • 未登录或未授权立即重定向,减少后续中间件与控制器开销。
  • 视图注入条件化
    • 工作台中间件在管理员上下文缺失或视图引擎不可用时跳过注入,降低无效计算。
  • 路由层统一处理
    • 路由层对“方法不允许/未找到”统一重定向,避免多次分支判断。

故障排查指南

  • 无法登录或频繁跳转登录页
    • 检查会话是否正确保存与恢复;确认 restoreFromSession 传入的 IP 与请求一致。
    • 查看认证中间件是否在管道最前执行。
  • 登录后仍提示无权限
    • 确认权限中间件在认证之后执行;检查 AdminGate::canAccess 的判定逻辑与白名单配置。
  • 模板变量缺失
    • 检查工作台中间件是否被跳过(管理员上下文为空或视图引擎不可用)。
  • 路由 404 或方法不允许
    • 查看路由解析结果;确认请求方法与路由定义一致。

结论

DouPHP 后台通过清晰的中间件分层实现了安全的认证与权限控制:认证中间件保障登录态,权限中间件实施模块级访问控制,工作台中间件按需注入视图上下文。配合路由层的统一处理与接口契约约束,系统具备良好的可维护性与扩展性。开发者可在不破坏现有链路的前提下,通过扩展 AdminGate 与新增中间件实现更细粒度的权限控制与安全策略。

附录:扩展与最佳实践

  • 扩展中间件功能
    • 新增自定义认证规则:在认证中间件前插入新中间件,复用 auth('admin') 守卫进行额外校验。
    • 添加细粒度权限控制:扩展 AdminGate::canAccess,结合资源维度(如 targetId)进行判定。
  • 添加自定义验证规则
    • 在权限中间件中增加前置校验步骤,例如检查请求签名、设备指纹或风控标记。
  • 实现细粒度权限控制
    • 基于模块+动作+资源 ID 的组合判定,支持行级权限控制。
  • 执行顺序建议
    • 安全相关中间件(认证、权限、CSRF、限流)应置于业务中间件之前。
    • 视图注入类中间件置于认证与权限之后,确保上下文完整。
  • 错误处理机制
    • 使用 HttpResponseException 短路返回,避免污染业务逻辑。
    • 统一重定向到登录页或首页,并附带友好提示。
  • 性能优化策略
    • 缓存权限判定结果(如基于角色的菜单与按钮权限)。
    • 避免在高频路径中进行昂贵计算或数据库查询。
添加日期:2026-10-05