文档目录
权限审计日志

简介

本文件面向 DouPHP 后台权限审计日志系统,系统性说明其设计原理、数据模型、采集机制、写入流程、查询展示、统计分析与安全策略。重点覆盖:

  • 用户操作记录、权限变更追踪、敏感操作监控
  • 审计日志的数据结构设计、日志级别与结果标记
  • 采集机制与同步写入实现
  • 后台查询界面与分页展示
  • 日志清理、归档与安全保护建议

项目结构

审计日志相关代码主要分布在以下位置:

  • 核心审计服务:core/service/audit/AuditService.php
  • 后台管理员日志模型与查询:admin/model/manager/ManagerAdminLog.php、admin/service/manager/ManagerService.php
  • 后台认证与授权:admin/middleware/AuthMiddleware.php、admin/service/authorization/AdminGate.php
  • 前端展示模板:admin/view/user_log.htm
  • 业务侧埋点示例:各模块 CategoryService / OptionService 等调用 audit()->writeAdminLog(...)
graph TB
A["业务控制器/服务<br/>如 CategoryService"] --> B["审计服务 AuditService"]
B --> C["数据库表 admin_log / user_log / book_log"]
D["后台管理 Service<br/>ManagerService"] --> E["日志模型 ManagerAdminLog"]
E --> C
F["后台中间件 AuthMiddleware"] --> G["授权判定 AdminGate"]
G --> A

核心组件

  • 审计服务 AuditService:统一封装会员、预约、后台三类审计日志的写入逻辑,负责 IP 来源、XSS 过滤、模块路由解析、失败快速校验等。
  • 管理员日志模型 ManagerAdminLog:提供按管理员、动作、模块、IP、时间范围筛选与默认排序的分页查询能力。
  • 后台管理 Service ManagerService:组装查询条件、执行分页、渲染行数据并返回给视图层。
  • 后台认证与授权:AuthMiddleware 恢复登录态;AdminGate 基于管理员类型与 action_list 进行模块访问控制。
  • 前端展示:user_log.htm 提供用户日志的筛选与列表展示。

架构总览

后台权限审计日志的整体流程如下:

  • 请求进入后台,先经认证中间件恢复管理员会话,再经授权中间件判断是否允许访问当前模块。
  • 业务服务在执行关键操作后,通过审计服务写入审计日志(包含管理员、动作、模块、结果、详情、IP、时间)。
  • 管理端通过 ManagerService 组合查询条件,使用 ManagerAdminLog 模型进行分页检索,最终由视图渲染列表。
sequenceDiagram
participant U as "管理员"
participant M as "AuthMiddleware"
participant G as "AdminGate"
participant S as "业务服务"
participant A as "AuditService"
participant DB as "数据库"
participant V as "ManagerService/视图"
U->>M : 发起后台请求
M->>M : 恢复管理员会话
M-->>U : 未登录则跳转登录
M->>G : 校验模块访问权限
G-->>S : 允许访问
S->>A : 写入审计日志admin_log
A->>DB : INSERT admin_log
U->>V : 查看审计日志列表
V->>DB : 分页查询 admin_log
DB-->>V : 返回日志列表
V-->>U : 渲染列表页面

详细组件分析

审计服务 AuditService

  • 职责:集中处理三类审计日志写入(用户、预约、后台),统一 IP 来源、XSS 过滤、模块解析、结果标记。
  • 关键方法:
    • writeUserLog:写入会员审计日志,字段包括用户ID、动作、IP、时间、结果、详情。
    • writeBookLog:写入预约审计日志,包含前后状态、操作者类型/ID、备注、IP、时间。
    • writeAdminLog:写入后台操作审计日志,强制要求 action 为字典常量,自动从 Session 回退管理员ID,自动解析 routeModule,并对 action/details 做 XSS 过滤。
  • 错误处理:当 action 为空或非字符串时抛出异常,避免脏数据写入。
flowchart TD
Start(["调用 writeAdminLog"]) --> CheckAction{"action 是否为非空字符串"}
CheckAction -- 否 --> ThrowErr["抛出参数异常"]
CheckAction -- 是 --> ResolveAdmin{"adminId 是否为0"}
ResolveAdmin -- 是 --> FromSession["从 Session 获取 admin_id"]
ResolveAdmin -- 否 --> UseInput["使用传入 adminId"]
FromSession --> Xss["对 action/details 做 XSS 过滤"]
UseInput --> Xss
Xss --> ResolveModule{"module 是否为空"}
ResolveModule -- 是 --> FromRequest["从 Request.routeModule() 取模块"]
ResolveModule -- 否 --> UseModule["使用传入 module"]
FromRequest --> WriteDB["INSERT admin_log"]
UseModule --> WriteDB
WriteDB --> End(["完成"])

管理员日志模型与查询 ManagerAdminLog / ManagerService

  • 模型能力:提供按管理员、动作、模块、IP、起止时间的筛选作用域,以及默认排序(id DESC)。
  • 查询流程:ManagerService 将请求参数转换为筛选条件,构建查询并分页,最后渲染行数据。
  • 典型用法:在管理后台“管理员日志”页面中,支持按管理员、动作、模块、IP、时间范围筛选,并分页展示。
classDiagram
class ManagerAdminLog {
+scopeFilterByAdminId(adminId)
+scopeFilterByAction(action)
+scopeFilterByModule(module)
+scopeFilterByIp(ip)
+scopeFilterByDateStartTs(ts)
+scopeFilterByDateEndTs(ts)
+scopeApplyDefaultOrder()
}
class ManagerService {
+buildAdminLogListData(params)
+renderAdminLogRow(row)
}
ManagerService --> ManagerAdminLog : "构建查询/分页"

后台认证与授权链

  • 认证中间件:恢复管理员会话,未登录则重定向到登录页。
  • 授权判定:根据管理员类型与 action_list 白名单判定是否可访问当前模块;子资源模块通过别名映射归一到父模块进行鉴权。
sequenceDiagram
participant R as "请求"
participant AM as "AuthMiddleware"
participant AG as "AdminGate"
participant C as "控制器/服务"
R->>AM : 进入后台路由
AM->>AM : restoreFromSession()
AM-->>R : 未登录 -> 跳转登录
AM->>AG : canAccess(admin, cur, action, targetId)
AG-->>C : 允许访问

业务侧审计埋点示例

  • 分类创建/更新/删除等操作在服务层完成后调用 audit()->writeAdminLog(...),记录管理员、动作、模块、结果与详情。
  • 示例路径:
    • 商品分类:CategoryService.php(商品分类):129-178
    • 投票选项:OptionService.php(投票选项):285-311

前端展示与查询界面

  • 用户日志页面 user_log.htm 提供筛选表单(用户名、动作、IP、起止时间)与列表展示(记录ID、账号、动作、IP、时间、结果、详情),并支持分页。
  • 该页面用于查看会员侧的用户日志,体现审计日志的可观测性。
flowchart TD
Q["用户日志查询表单"] --> F["提交筛选条件"]
F --> L["后端返回日志列表"]
L --> T["表格渲染:ID/账号/动作/IP/时间/结果/详情"]
T --> P["分页控件"]

依赖关系分析

  • AuditService 依赖:
    • 数据库访问:通过 ORM 插入 admin_log / user_log / book_log
    • 会话:读取 admin_id(当传入为0时)
    • 请求:解析 routeModule(当 module 为空时)
  • ManagerService 依赖:
    • ManagerAdminLog 模型:提供筛选作用域与分页
  • 中间件与授权:
    • AuthMiddleware 依赖认证守卫
    • AdminGate 依赖管理员上下文与 action_list 白名单
graph LR
AS["AuditService"] --> DB["数据库"]
AS --> SESS["Session"]
AS --> REQ["Request"]
MS["ManagerService"] --> MA["ManagerAdminLog"]
AMW["AuthMiddleware"] --> AUTH["认证守卫"]
AG["AdminGate"] --> ADMIN["管理员上下文"]

性能与存储优化

  • 写入性能:
    • 当前实现为同步写入数据库,适合中小规模后台场景。高并发下可考虑异步队列写入(例如消息队列或任务调度),但需保证幂等与顺序性。
  • 存储优化:
    • 建议在 admin_log 上建立索引:admin_id、action、module、ip、created_at,以加速筛选与分页。
    • 对 details 大字段可考虑压缩或分表存储。
  • 查询性能:
    • 使用 ManagerAdminLog 的作用域精确筛选,避免全表扫描。
    • 分页大小适中(默认15条),可按需调整。
  • 安全与合规:
    • 已对 action/details 做 XSS 过滤,防止注入与脚本攻击。
    • 建议对敏感字段(如 IP、details)进行脱敏展示与访问审计。

查询、报表与告警

  • 查询能力:
    • 管理员日志:支持按管理员、动作、模块、IP、起止时间筛选,分页展示。
    • 用户日志:支持按用户名、动作、IP、起止时间筛选,分页展示。
  • 报表生成:
    • 可在 ManagerService 层扩展聚合统计(如按动作、模块、管理员维度计数),导出 CSV/Excel。
  • 异常告警:
    • 可基于审计日志中的 result=失败 或特定 action(如删除、权限变更)设置阈值告警(邮件/短信/IM)。
    • 建议结合外部监控系统(如 Prometheus + Alertmanager)对高频失败或敏感操作进行实时告警。

清理、归档与安全

  • 清理策略:
    • 定期清理历史日志(如保留最近90天),可通过定时任务删除过期记录。
    • 对低频访问的历史数据进行归档(冷存储),降低主库压力。
  • 归档方案:
    • 将旧数据迁移至独立库或对象存储,保留必要索引以便回溯。
  • 安全措施:
    • 限制审计日志的访问权限(仅超级管理员或审计角色)。
    • 对日志导出增加二次确认与水印,防止泄露。
    • 对写入接口增加速率限制与防抖,避免恶意刷写。

故障排查指南

  • 常见问题:
    • 审计日志缺失:检查业务服务是否正确调用 audit()->writeAdminLog(...),并确保 action 为合法常量。
    • 模块名为空:确认路由已正确设置 routeModule,或在调用时显式传入 module。
    • 管理员ID为空:当传入 adminId 为0时,会从 Session 回退;若仍为空,检查登录态是否正常。
    • XSS 过滤导致内容截断:确保 details 为纯文本,富文本内容应使用专用方法处理。
  • 定位步骤:
    • 查看审计服务写入逻辑,确认参数与返回值。
    • 检查 ManagerService 的筛选条件与分页结果。
    • 核对数据库记录是否存在,必要时开启慢查询日志。

结论

DouPHP 后台权限审计日志系统通过统一的审计服务、清晰的模型与查询能力、严格的认证授权链路,实现了用户操作记录、权限变更追踪与敏感操作监控。当前实现采用同步写入与精确筛选,满足大多数后台场景需求。未来可在此基础上引入异步写入、聚合报表与告警机制,进一步提升可观测性与运维效率。同时,建议完善清理归档与安全保护措施,确保审计数据的长期可用性与合规性。

添加日期:2026-10-05