简介
本文件为 DouPHP 框架的“内置中间件”权威文档,覆盖后台、前台、API 三端的中间件能力与使用方式。内容涵盖 CSRF 保护、安全响应头、请求限流、用户认证、权限验证等,并说明各中间件的执行时机、配置项、参数含义、典型用法、最佳实践、执行顺序与组合策略,以及常见问题排查。
项目结构
DouPHP 将中间件按端侧划分:
- 后台(admin):认证、权限、CSRF、安全响应头
- 前台(front):会员认证、CSRF、限流、安全响应头
- API(api):会员认证、限流、安全响应头
graph TB
subgraph "后台"
A_AdminAuth["认证中间件"]
A_Permission["权限中间件"]
A_Csrf["CSRF 中间件"]
A_Sec["安全响应头中间件"]
end
subgraph "前台"
F_UserAuth["会员认证中间件"]
F_Csrf["CSRF 中间件"]
F_Throttle["限流中间件"]
F_Sec["安全响应头中间件"]
end
subgraph "API"
Api_UserAuth["会员认证中间件"]
Api_Throttle["限流中间件"]
Api_Sec["安全响应头中间件"]
end
Client["客户端"] --> |浏览器/移动端| F_UserAuth
Client --> |浏览器/移动端| F_Csrf
Client --> |浏览器/移动端| F_Throttle
Client --> |浏览器/移动端| F_Sec
Client --> |管理后台| A_AdminAuth
Client --> |管理后台| A_Permission
Client --> |管理后台| A_Csrf
Client --> |管理后台| A_Sec
Client --> |API 调用| Api_UserAuth
Client --> |API 调用| Api_Throttle
Client --> |API 调用| Api_Sec
图示来源
- admin/middleware/AuthMiddleware.php:24-50
- admin/middleware/PermissionMiddleware.php:25-70
- admin/middleware/CsrfMiddleware.php:24-79
- admin/middleware/SecurityHeadersMiddleware.php:23-28
- front/middleware/UserAuthMiddleware.php:26-98
- front/middleware/CsrfMiddleware.php:24-95
- front/middleware/ThrottleMiddleware.php:24-83
- front/middleware/SecurityHeadersMiddleware.php:23-28
- api/middleware/UserAuthMiddleware.php:25-93
- api/middleware/ThrottleMiddleware.php:25-89
- api/middleware/SecurityHeadersMiddleware.php:23-28
章节来源
- admin/middleware/AuthMiddleware.php:24-50
- admin/middleware/PermissionMiddleware.php:25-70
- admin/middleware/CsrfMiddleware.php:24-79
- admin/middleware/SecurityHeadersMiddleware.php:23-28
- front/middleware/UserAuthMiddleware.php:26-98
- front/middleware/CsrfMiddleware.php:24-95
- front/middleware/ThrottleMiddleware.php:24-83
- front/middleware/SecurityHeadersMiddleware.php:23-28
- api/middleware/UserAuthMiddleware.php:25-93
- api/middleware/ThrottleMiddleware.php:25-89
- api/middleware/SecurityHeadersMiddleware.php:23-28
核心组件
- 后台认证中间件:从会话恢复管理员登录态,未登录跳转登录页。
- 后台权限中间件:校验管理员对当前模块/动作的访问权限。
- 后台 CSRF 中间件:基于静态令牌或一次性令牌校验表单提交,异常时给出可操作提示并重定向。
- 后台安全响应头中间件:统一设置基线安全响应头。
- 前台会员认证中间件:解析前端登录态,支持 XHR 场景返回 JSON 401 并附带跳转地址。
- 前台 CSRF 中间件:区分一次性令牌路由与共享静态令牌,GET 带 token 链接也校验。
- 前台限流中间件:对敏感接口按 IP 限流,超限提示并重定向首页。
- 前台安全响应头中间件:统一设置基线安全响应头。
- API 会员认证中间件:从 Authorization Bearer 提取 token,按配置模式进行 required/optional/public 决策,必要时校验工作端身份。
- API 限流中间件:对登录注册、短信验证码、公共写接口、防伪查询、LLM 成本端点按 IP 限流,超限返回 JSON 429。
- API 安全响应头中间件:统一设置基线安全响应头。
章节来源
- admin/middleware/AuthMiddleware.php:24-50
- admin/middleware/PermissionMiddleware.php:25-70
- admin/middleware/CsrfMiddleware.php:24-79
- admin/middleware/SecurityHeadersMiddleware.php:23-28
- front/middleware/UserAuthMiddleware.php:26-98
- front/middleware/CsrfMiddleware.php:24-95
- front/middleware/ThrottleMiddleware.php:24-83
- front/middleware/SecurityHeadersMiddleware.php:23-28
- api/middleware/UserAuthMiddleware.php:25-93
- api/middleware/ThrottleMiddleware.php:25-89
- api/middleware/SecurityHeadersMiddleware.php:23-28
架构总览
中间件在请求进入控制器之前依次执行,形成“管道”。不同端侧的中间件职责清晰分离:
- 后台:认证 → 权限 → CSRF → 安全响应头
- 前台:认证(可选)→ CSRF → 限流 → 安全响应头
- API:认证(按配置)→ 限流 → 安全响应头
sequenceDiagram
participant C as "客户端"
participant MW as "中间件管道"
participant CTRL as "控制器"
participant RESP as "响应"
C->>MW : "HTTP 请求"
MW->>MW : "认证/权限/CSRF/限流/安全头"
alt 通过
MW->>CTRL : "继续处理"
CTRL-->>RESP : "业务响应"
RESP-->>C : "HTTP 响应"
else 拒绝
MW-->>C : "重定向/错误响应"
end
图示来源
- admin/middleware/AuthMiddleware.php:42-50
- admin/middleware/PermissionMiddleware.php:49-70
- admin/middleware/CsrfMiddleware.php:47-79
- front/middleware/UserAuthMiddleware.php:47-98
- front/middleware/CsrfMiddleware.php:62-95
- front/middleware/ThrottleMiddleware.php:58-83
- api/middleware/UserAuthMiddleware.php:47-93
- api/middleware/ThrottleMiddleware.php:64-89
详细组件分析
后台认证中间件(Admin Auth)
- 功能:从会话恢复管理员登录态;未登录则跳转到后台登录页。
- 执行时机:请求进入后台路由后最先执行,确保后续中间件和控制器能读取到管理员身份。
- 关键行为:
- 使用 Guard 恢复登录态。
- 未登录抛出响应异常,由框架统一处理跳转。
- 豁免策略:登录入口通过路由级声明式豁免,不在中间件内硬编码名单。
flowchart TD
Start(["进入后台"]) --> Restore["恢复管理员登录态"]
Restore --> HasUser{"是否已登录?"}
HasUser -- "否" --> Redirect["跳转登录页"]
HasUser -- "是" --> Next["放行至下一中间件/控制器"]
图示来源
- admin/middleware/AuthMiddleware.php:42-50
章节来源
- admin/middleware/AuthMiddleware.php:24-50
后台权限中间件(Admin Permission)
- 功能:校验管理员对当前模块/动作的访问权限;超级管理员直接放行。
- 执行时机:认证通过后执行,确保只有具备权限的管理员才能访问对应模块。
- 关键行为:
- 读取当前模块、动作与目标 ID。
- 调用授权门控判定是否允许访问。
- 无权限时重定向至后台首页。
flowchart TD
S(["进入权限检查"]) --> Read["读取模块/动作/目标ID"]
Read --> Gate{"是否有权访问?"}
Gate -- "否" --> Deny["重定向到后台首页"]
Gate -- "是" --> Allow["放行"]
图示来源
- admin/middleware/PermissionMiddleware.php:49-70
章节来源
- admin/middleware/PermissionMiddleware.php:25-70
后台 CSRF 中间件(Admin CSRF)
- 功能:校验后台表单提交,防止跨站请求伪造。
- 令牌模型:
- 默认使用共享静态令牌。
- 特定路由使用一次性令牌(如找回密码提交)。
- 部分 GET 链接(备份/导入/报表导出)也需携带令牌校验。
- 失败处理:抛出领域异常,由后台消息处理器输出友好提示并重定向。
flowchart TD
In(["POST/GET 请求"]) --> Map["映射令牌ID"]
Map --> Validate{"令牌有效?"}
Validate -- "否" --> Reject["抛出异常并提示"]
Validate -- "是" --> Pass["放行"]
图示来源
- admin/middleware/CsrfMiddleware.php:47-79
章节来源
- admin/middleware/CsrfMiddleware.php:24-79
后台安全响应头中间件(Admin Security Headers)
- 功能:为后台响应设置基线安全头(具体策略由基类实现)。
- 执行时机:请求处理完成后设置响应头。
- 适用场景:所有后台页面与资源。
章节来源
- admin/middleware/SecurityHeadersMiddleware.php:23-28
前台会员认证中间件(Front User Auth)
- 功能:解析前台会员登录态;支持 XHR 场景返回 JSON 401 并附带跳转地址。
- 执行时机:进入前台路由后执行,若要求登录则拦截未登录请求。
- 关键行为:
- 通过 Guard 解析登录态并注入上下文。
- 当 from=js 时返回 JSON 错误与跳转地址,便于前端处理。
- 普通页面未登录时重定向到登录页并保留原地址。
sequenceDiagram
participant U as "用户"
participant F as "前台认证中间件"
participant G as "Guard"
U->>F : "请求"
F->>G : "解析登录态"
alt 已登录
G-->>F : "用户上下文"
F-->>U : "放行"
else 未登录且XHR
G-->>F : "无上下文"
F-->>U : "JSON 401 + jump_url"
else 未登录且普通页面
G-->>F : "无上下文"
F-->>U : "重定向到登录页"
end
图示来源
- front/middleware/UserAuthMiddleware.php:47-98
章节来源
- front/middleware/UserAuthMiddleware.php:26-98
前台 CSRF 中间件(Front CSRF)
- 功能:校验前台表单与带 token 的 GET 链接,防止 CSRF。
- 令牌模型:
- 9 类一次性令牌路由(登录、注册、找回密码、留言、落地页、分销申请、咨询等)。
- 其余使用共享静态令牌。
- 指定 GET 路由(取消预约、商家处理、余额扣款、购物车销毁、订单取消、登出)也校验。
- 失败处理:抛出领域异常,提示并重定向首页。
flowchart TD
Req["请求到达"] --> Type{"是否一次性令牌路由?"}
Type -- "是" --> OneTime["使用一次性令牌"]
Type -- "否" --> Static["使用共享静态令牌"]
OneTime --> Check{"令牌有效?"}
Static --> Check
Check -- "否" --> Expired["提示并返回首页"]
Check -- "是" --> OK["放行"]
图示来源
- front/middleware/CsrfMiddleware.php:62-95
章节来源
- front/middleware/CsrfMiddleware.php:24-95
前台限流中间件(Front Throttle)
- 功能:对敏感端点按 IP 限流,包括登录、注册、手机号登录、找回密码、短信验证码下发、公共表单提交、聊天相关端点。
- 失败处理:设置 Retry-After 响应头,抛出领域异常并返回首页。
- 设计要点:与业务层限流互补,前置拦截高频请求,降低后端压力。
flowchart TD
R["请求"] --> Match{"匹配限流规则?"}
Match -- "否" --> Pass["放行"]
Match -- "是" --> Count["统计次数"]
Count --> Over{"超过配额?"}
Over -- "是" --> Limit["返回429并提示"]
Over -- "否" --> Pass
图示来源
- front/middleware/ThrottleMiddleware.php:58-83
章节来源
- front/middleware/ThrottleMiddleware.php:24-83
前台安全响应头中间件(Front Security Headers)
- 功能:为前台响应设置基线安全头(具体策略由基类实现)。
- 适用场景:所有前台页面与资源。
章节来源
- front/middleware/SecurityHeadersMiddleware.php:23-28
API 会员认证中间件(API User Auth)
- 功能:从 Authorization: Bearer 提取 token,解析会员登录态;按配置模式进行 required/optional/public 决策;必要时校验工作端身份。
- 配置来源:API 端 init/middleware.php 中的 auth_modes 与 work_required。
- 失败处理:未登录返回 JSON 401;无工作端身份返回 JSON 403。
sequenceDiagram
participant App as "应用"
participant AuthMW as "API认证中间件"
participant Guard as "API Guard"
participant Policy as "策略(配置文件)"
App->>AuthMW : "HTTP 请求"
AuthMW->>Policy : "读取auth_modes/work_required"
AuthMW->>Guard : "解析Bearer Token"
alt public
AuthMW-->>App : "放行"
else optional
AuthMW->>Guard : "尝试解析登录态"
alt 解析成功
AuthMW-->>App : "放行"
else 解析失败
AuthMW-->>App : "放行(不强制)"
end
else required
AuthMW->>Guard : "必须登录"
alt 已登录
AuthMW-->>App : "放行"
else 未登录
AuthMW-->>App : "JSON 401"
end
end
Note over AuthMW,Policy : "work_required命中时额外校验工作端身份"
图示来源
- api/middleware/UserAuthMiddleware.php:47-93
- api/init/middleware.php:18-146
章节来源
- api/middleware/UserAuthMiddleware.php:25-93
- api/init/middleware.php:18-146
API 限流中间件(API Throttle)
- 功能:对登录/注册/手机登录/找回密码/短信验证码下发、公共匿名写接口、防伪查询、LLM 成本端点按 IP 限流。
- 失败处理:设置 Retry-After 响应头,返回 JSON 429。
- 设计要点:针对高成本或易滥用端点收紧频率,保护系统稳定性。
flowchart TD
Q["API请求"] --> Rule{"匹配限流规则?"}
Rule -- "否" --> Ok["放行"]
Rule -- "是" --> Check["计数窗口"]
Check --> Exceed{"超限?"}
Exceed -- "是" --> RateLimit["返回429并设置Retry-After"]
Exceed -- "否" --> Ok
图示来源
- api/middleware/ThrottleMiddleware.php:64-89
章节来源
- api/middleware/ThrottleMiddleware.php:25-89
API 安全响应头中间件(API Security Headers)
- 功能:为 API 响应设置基线安全头(具体策略由基类实现)。
- 适用场景:所有 API 接口。
章节来源
- api/middleware/SecurityHeadersMiddleware.php:23-28
依赖关系分析
- 后台中间件依赖链:
- 认证中间件先于权限中间件执行,确保权限检查时有管理员上下文。
- 权限中间件依赖授权门控服务。
- CSRF 中间件依赖令牌服务与语言包。
- 安全响应头中间件依赖基类实现。
- 前台中间件依赖链:
- 认证中间件依赖 Guard 与语言包。
- CSRF 中间件依赖令牌服务与语言包。
- 限流中间件依赖抽象限流基类与语言包。
- 安全响应头中间件依赖基类实现。
- API 中间件依赖链:
- 认证中间件依赖 Guard、策略配置与 API 响应封装。
- 限流中间件依赖抽象限流基类与 API 响应封装。
- 安全响应头中间件依赖基类实现。
graph LR
AdminAuth["后台认证"] --> AdminPerm["后台权限"]
AdminPerm --> AdminCsrf["后台CSRF"]
AdminCsrf --> AdminSec["后台安全头"]
FrontAuth["前台认证"] --> FrontCsrf["前台CSRF"]
FrontCsrf --> FrontThrottle["前台限流"]
FrontThrottle --> FrontSec["前台安全头"]
ApiAuth["API认证"] --> ApiThrottle["API限流"]
ApiThrottle --> ApiSec["API安全头"]
图示来源
- admin/middleware/AuthMiddleware.php:42-50
- admin/middleware/PermissionMiddleware.php:49-70
- admin/middleware/CsrfMiddleware.php:47-79
- front/middleware/UserAuthMiddleware.php:47-98
- front/middleware/CsrfMiddleware.php:62-95
- front/middleware/ThrottleMiddleware.php:58-83
- api/middleware/UserAuthMiddleware.php:47-93
- api/middleware/ThrottleMiddleware.php:64-89
章节来源
- admin/middleware/AuthMiddleware.php:24-50
- admin/middleware/PermissionMiddleware.php:25-70
- admin/middleware/CsrfMiddleware.php:24-79
- front/middleware/UserAuthMiddleware.php:26-98
- front/middleware/CsrfMiddleware.php:24-95
- front/middleware/ThrottleMiddleware.php:24-83
- api/middleware/UserAuthMiddleware.php:25-93
- api/middleware/ThrottleMiddleware.php:25-89
性能与限流
- 限流策略:
- 前台:对登录、注册、手机登录、找回密码、短信验证码、公共表单、聊天相关端点按 IP 限流,避免恶意刷量。
- API:对登录注册、短信验证码、公共写接口、防伪查询、LLM 成本端点按 IP 限流,超限返回 429。
- 建议:
- 在高并发场景下,优先在前置中间件层限流,减少后端计算与 I/O。
- 合理设置窗口与最大次数,平衡用户体验与安全性。
- 结合业务层限流(如登录失败限制)形成双重防护。
故障排除指南
- 后台 CSRF 校验失败:
- 现象:提示页面过期或非法请求,重定向到后台首页。
- 原因:会话过期、令牌旋转、表单未携带正确令牌。
- 处理:刷新页面重新获取令牌;确认表单渲染了 csrf()->token();检查 GET 链接是否携带 token。
- 参考路径:admin/middleware/CsrfMiddleware.php:68-79
- 前台 CSRF 校验失败:
- 现象:提示页面过期或非法请求,重定向到首页。
- 原因:一次性令牌失效、共享静态令牌过期、GET 链接缺少 token。
- 处理:刷新页面;确认一次性令牌路由使用了正确的令牌;检查 GET 链接是否包含 token。
- 参考路径:front/middleware/CsrfMiddleware.php:85-95
- 前台限流触发:
- 现象:短时间内多次请求被拒绝,返回错误或提示。
- 原因:达到 IP 限流阈值。
- 处理:降低请求频率;检查是否有重复提交;调整业务重试逻辑。
- 参考路径:front/middleware/ThrottleMiddleware.php:69-83
- API 限流触发:
- 现象:返回 JSON 429,包含 Retry-After。
- 原因:达到 IP 限流阈值。
- 处理:等待重试;优化客户端重试策略;检查是否批量请求。
- 参考路径:api/middleware/ThrottleMiddleware.php:75-89
- API 认证失败:
- 现象:返回 JSON 401 或 403。
- 原因:未携带有效 Bearer token;或命中 work_required 但无工作端身份。
- 处理:确认 Authorization 头格式;检查 api/init/middleware.php 中 auth_modes 配置;如需工作端身份,确保 token 包含 workId。
- 参考路径:api/middleware/UserAuthMiddleware.php:77-93, api/init/middleware.php:18-146
- 前台认证失败(XHR):
- 现象:返回 JSON 401 并附带 jump_url。
- 原因:未登录或会话过期。
- 处理:前端捕获 401 并跳转到 jump_url;引导用户重新登录。
- 参考路径:front/middleware/UserAuthMiddleware.php:77-89
章节来源
- admin/middleware/CsrfMiddleware.php:68-79
- front/middleware/CsrfMiddleware.php:85-95
- front/middleware/ThrottleMiddleware.php:69-83
- api/middleware/ThrottleMiddleware.php:75-89
- api/middleware/UserAuthMiddleware.php:77-93
- api/init/middleware.php:18-146
- front/middleware/UserAuthMiddleware.php:77-89
结论
DouPHP 的内置中间件以端侧为单位提供了完整的安全与治理能力:后台侧重认证与权限,前台侧重 CSRF 与限流,API 侧重认证策略与限流。通过清晰的执行顺序与可配置的豁免策略,开发者可以在不同场景下灵活组合中间件,保障系统的安全性、可用性与性能。
附录:配置与组合策略
常见配置场景
- 后台表单提交:
- 启用 CSRF 中间件;模板渲染时使用 csrf()->token();提交时自动校验。
- 参考路径:admin/middleware/CsrfMiddleware.php:24-79
- 前台会员私有接口:
- 启用前台认证中间件;未登录时重定向登录页;XHR 返回 JSON 401 与跳转地址。
- 参考路径:front/middleware/UserAuthMiddleware.php:26-98
- API 公开与私有接口:
- 在 api/init/middleware.php 中为每个模块/动作配置 auth_modes(public/optional/required),必要时叠加 work_required。
- 参考路径:api/init/middleware.php:18-146
- 敏感接口限流:
- 前台:登录、注册、手机登录、找回密码、短信验证码、公共表单、聊天相关端点。
- API:登录注册、短信验证码、公共写接口、防伪查询、LLM 成本端点。
- 参考路径:front/middleware/ThrottleMiddleware.php:32-50, api/middleware/ThrottleMiddleware.php:33-56
执行顺序建议
- 后台:认证 → 权限 → CSRF → 安全响应头
- 前台:认证(可选)→ CSRF → 限流 → 安全响应头
- API:认证(按配置)→ 限流 → 安全响应头
最佳实践
- 使用路由级声明式豁免免登入口,避免在中间件内硬编码名单。
- 对一次性令牌路由明确映射,减少 CSRF 误判。
- 对高成本或易滥用端点收紧限流策略,提升系统稳定性。
- 在 API 端严格登记 auth_modes,防止新模块静默上线为匿名可访问。
- 结合业务层限流与中间件限流,形成多层防护。