文档目录
会话安全配置

简介

本指南面向 DouPHP 开发者,聚焦“会话安全”的落地实践:如何正确配置 Cookie 的安全属性(HttpOnly、Secure、SameSite),如何防御会话固定攻击,如何实现会话超时与销毁,以及多端应用(Web、API、小程序)与分布式环境下的会话管理策略。文档基于仓库中的实际代码路径与实现进行说明,并提供可操作的配置建议与安全最佳实践。

项目结构

DouPHP 将安全相关配置集中在统一的安全配置文件中,并在各端初始化阶段启动会话;登录态与会话校验由前台认证门面与中间件共同完成;CSRF 防护贯穿后台与前端资源加载流程。

graph TB
A["安全配置<br/>config/security.php"] --> B["会话启动<br/>front/init/Init.php"]
A --> C["会话启动<br/>admin/init/Init.php"]
B --> D["会话门面/存储<br/>core/facade/Session.php<br/>core/infra/session/Session.php"]
B --> E["前台认证与心跳<br/>front/facade/Auth.php"]
C --> F["后台认证中间件<br/>admin/middleware/AuthMiddleware.php"]
C --> G["后台 CSRF 中间件<br/>admin/middleware/CsrfMiddleware.php"]
G --> H["前端自动注入 CSRF Token<br/>admin/view/js/dou.csrf.js"]

核心组件

  • 安全配置中心:集中定义可信代理、可信 Host、安全响应头、限流与会话 Cookie 硬化参数。
  • 会话门面与存储:提供统一的 Session 操作接口,封装命名空间隔离、清空、数组操作等能力。
  • 前台认证 Guard:负责凭据校验、登录态写入、会话恢复、会话心跳刷新与登出清理。
  • 后台认证中间件:在请求进入控制器前恢复管理员会话,未登录则重定向到登录页。
  • CSRF 防护:后台通过中间件校验表单令牌,前端 JS 自动为 AJAX/Fetch 注入 CSRF Token。

架构总览

下图展示了从请求进入、会话启动、认证恢复到敏感操作校验的完整链路,并标注了关键安全点。

sequenceDiagram
participant Client as "客户端"
participant FrontInit as "前台初始化<br/>front/init/Init.php"
participant AdminInit as "后台初始化<br/>admin/init/Init.php"
participant AuthFront as "前台认证<br/>front/facade/Auth.php"
participant AuthAdmin as "后台认证中间件<br/>admin/middleware/AuthMiddleware.php"
participant Csrf as "后台CSRF中间件<br/>admin/middleware/CsrfMiddleware.php"
participant Session as "会话存储<br/>core/infra/session/Session.php"
Client->>FrontInit : 发起请求
FrontInit->>FrontInit : 启动会话(应用安全Cookie配置)
FrontInit->>AuthFront : 尝试恢复登录态/校验会话
AuthFront->>Session : 读取/更新会话数据(ontime等)
Note over AuthFront,Session : 会话心跳与超时控制
Client->>AdminInit : 访问后台
AdminInit->>AdminInit : 启动会话(应用安全Cookie配置)
AdminInit->>AuthAdmin : 恢复管理员会话
AuthAdmin-->>Client : 未登录则重定向至登录页
Client->>Csrf : 提交表单/AJAX
Csrf->>Csrf : 校验CSRF令牌(静态或一次性)
Csrf-->>Client : 校验失败返回错误提示

详细组件分析

会话 Cookie 安全配置(HttpOnly、Secure、SameSite)

  • 配置位置:安全配置文件中定义了 session 子项,包含 httponly、secure、samesite、use_strict_mode。
  • 生效时机:各端 Init 在启动会话前应用这些配置,确保会话 Cookie 自创建即具备安全属性。
  • 推荐设置:
    • HttpOnly:始终启用,防止 JavaScript 读取会话 ID,降低 XSS 窃取风险。
    • Secure:生产环境强制 HTTPS 时开启;混合部署时可跟随运行时协议。
    • SameSite:默认 Lax;跨站场景按需调整,避免 None 滥用导致 CSRF 风险上升。
    • use_strict_mode:建议开启,拒绝未初始化的外部 sid,缓解会话固定攻击。

会话固定攻击防护

  • 机制要点:
    • 使用严格模式拒绝未初始化的外部会话 ID。
    • 登录成功后立即重新生成会话 ID,避免沿用旧 ID。
    • 会话凭证采用 shell 校验(结合用户字段与系统密钥),每次请求验证一致性。
  • 实现位置:
    • 安全配置中启用严格模式。
    • 前台认证在成功登录后执行会话 ID 再生并写入 shell、时间戳等。
    • 后续请求通过匹配会话与数据库状态进行校验。
flowchart TD
Start(["登录成功"]) --> Regenerate["重新生成会话ID"]
Regenerate --> WriteShell["写入shell与时间戳等会话数据"]
WriteShell --> NextReq["后续请求"]
NextReq --> Verify{"会话与数据库一致?"}
Verify --> |是| Touch["刷新会话心跳"]
Verify --> |否| Clear["清理会话并视为未登录"]
Touch --> End(["继续处理请求"])
Clear --> End

会话超时管理与心跳刷新

  • 心跳刷新:前台认证提供 touchSession 方法,按配置的超时阈值判断是否过期;过期则清理会话。
  • 使用方式:在受保护的业务入口调用心跳刷新,延长活跃会话的生命周期。
  • 效果:避免长时间无交互的会话被恶意利用,同时保证正常用户的连续体验。

会话销毁机制

  • 登出清理:前台认证 logout 会删除 remember-me 凭证 Cookie,并清空会话命名空间,重置实例状态。
  • 后台认证:中间件在未恢复管理员会话时直接重定向到登录页,不保留任何敏感上下文。
  • 建议:在敏感操作(如修改密码、支付确认)后主动触发登出或会话重建,降低会话劫持窗口。

多端应用的会话同步策略

  • Web 端:基于会话 Cookie 的有状态登录,配合 CSRF 与心跳管理。
  • API 端:采用无状态 token 方案,服务端签发不可逆哈希的 token 并下发给客户端;请求携带 Authorization 头进行鉴权。
  • 小程序端:本地持久化 token 与用户标识,退出时清除本地缓存;服务端同样以 token 校验身份。
  • 同步原则:
    • 不同端之间不共享同一会话 ID,避免跨端污染。
    • 统一使用服务端签发的 token 作为跨端凭证,减少 Cookie 依赖。
    • 对敏感操作要求二次校验(如短信验证码、设备指纹)。

分布式环境下的会话管理方案

  • 目标:在多节点或多进程环境下保证会话一致性与高可用。
  • 方案建议:
    • 将会话存储迁移至 Redis 或数据库,避免本地文件存储导致的单点问题。
    • 统一会话键命名空间,避免不同模块冲突。
    • 配置负载均衡器保持粘性会话或使用共享存储。
    • 对会话数据进行加密与签名,防止篡改。
  • 注意:当前仓库中的会话门面与存储提供了命名空间隔离与清空能力,可作为扩展基础。

CSRF 防护与令牌管理

  • 后台 CSRF:中间件根据路由选择令牌模型(静态或一次性),校验失败返回友好提示。
  • 前端注入:JS 自动为 jQuery AJAX 与 fetch 请求注入 X-CSRF-Token 请求头。
  • 豁免策略:登录提交等匿名接口通过路由级声明式豁免,避免死循环。
sequenceDiagram
participant Browser as "浏览器"
participant Js as "CSRF脚本<br/>dou.csrf.js"
participant Middleware as "CSRF中间件<br/>CsrfMiddleware"
participant Controller as "控制器"
Browser->>Js : 页面加载
Js->>Browser : 为AJAX/Fetch注入X-CSRF-Token
Browser->>Middleware : POST /xxx
Middleware->>Middleware : 校验令牌(静态/一次性)
Middleware-->>Controller : 校验通过放行
Middleware-->>Browser : 校验失败返回错误

依赖关系分析

  • 安全配置驱动会话启动:Init 在启动会话前读取安全配置并应用 Cookie 属性。
  • 认证与中间件协作:前台认证负责会话恢复与心跳,后台中间件负责权限拦截。
  • CSRF 与业务解耦:中间件统一校验,前端脚本自动注入令牌,控制器无需关心细节。
graph LR
SecCfg["安全配置<br/>security.php"] --> InitFront["前台Init"]
SecCfg --> InitAdmin["后台Init"]
InitFront --> AuthFront["前台认证"]
InitAdmin --> AuthAdmin["后台认证中间件"]
AuthAdmin --> Csrf["CSRF中间件"]
Csrf --> JsInject["前端CSRF注入"]

性能考虑

  • 会话心跳:仅在必要入口调用,避免频繁写库或写存储。
  • CSRF 校验:中间件层统一处理,开销可控;避免在高频 GET 请求上引入额外负担。
  • 分布式存储:Redis 等高并发后端可降低锁竞争,提升吞吐。
  • 最小化会话数据:仅存放必要标识,避免大对象序列化影响性能。

故障排查指南

  • 会话无效:检查安全配置中的 secure 与 samesite 是否与部署环境匹配;确认 HTTPS 与域名设置。
  • 登录失败:查看前台认证的 IP 限流与账号锁定逻辑;核对凭据与验证码有效性。
  • CSRF 错误:确认前端是否注入 X-CSRF-Token;检查路由是否误豁免或令牌模型选择不当。
  • 会话固定:确认已启用严格模式;检查登录成功后是否重新生成会话 ID。

结论

DouPHP 通过集中化的安全配置、严格的会话生命周期管理、完善的 CSRF 防护以及多端一致的认证策略,构建了较为健壮的会话安全体系。开发者应遵循本文的配置建议与实践,在生产环境中启用 HttpOnly、Secure、SameSite 与严格模式,合理设置会话超时,并在分布式环境下采用共享存储方案,以确保会话安全与可用性。

附录

  • 常见安全问题与解决方案:
    • 会话固定:启用严格模式 + 登录成功后重新生成会话 ID。
    • 会话劫持:启用 HttpOnly 与 Secure,限制 SameSite,缩短会话有效期。
    • CSRF 攻击:使用 CSRF 令牌,前端自动注入,后端严格校验。
    • 跨域 Cookie:谨慎使用 SameSite=None,确保 HTTPS 且明确信任源。
    • 多端不一致:统一使用服务端签发的 token,避免 Cookie 跨端污染。
添加日期:2026-10-05