拦截项目中的敏感操作
本文最后更新于 2025年7月23日 15:05
分析现有日志中间件执行流程
init
方法:注册日志中间件,使用once.Do()
保证processLogs
协程以单例模式存在。Shutdown
方法:优雅关闭日志处理器。logFilterHandle
方法:实现了真正的日志记录逻辑,这里可以类比 Java 中的 AOP 来理解,以一种环绕通知的方式实现了日志记录。sequenceDiagram participant Client participant logFilterHandle participant BusinessLogic participant logChan participant processLogs Client->>logFilterHandle: 发起请求 alt 正在关闭? logFilterHandle->>BusinessLogic: 直接调用next() else 正常处理 logFilterHandle->>logFilterHandle: 提取请求信息 logFilterHandle->>BusinessLogic: 调用next() BusinessLogic-->>logFilterHandle: 返回响应/错误 logFilterHandle->>logChan: 异步发送日志条目 Note right of logChan: 非阻塞操作 logChan->>processLogs: 传递日志条目 processLogs->>processLogs: 批量处理日志 end logFilterHandle-->>Client: 返回响应
processLogs
方法:通过一个 for 循环持续监听 logChan 和 shutdown 两个 Channel;并且通过 Channel 和 select 实现日志的异步处理,避免阻塞主流程;通过批量写入来减少I/O操作,提升性能。flowchart TD A[开始循环] --> B{select监听} B -->|logChan| C{通道关闭?} C -- 是 --> D[处理剩余日志并退出] C -- 否 --> E[追加日志到缓冲区] E --> F{缓冲区满?} F -- 是 --> G[批量写入并清空缓冲区] F -- 否 --> B B -->|shutdown| H[处理剩余日志并退出]
哪些请求会被拦截
在 configs/trpc_go_{env}.yaml
中,日志中间件被显式注册到 trpc.cloud.pms.Services.http
服务的 filter
列表中:
1 |
|
因此只有 trpc.cloud.pms.Services.http
这个服务的请求会被拦截(也就是所有的 http 请求),然后走日志中间件的处理逻辑。
梳理 service.go
中的增删改操作
1. Add 相关方法:4个
- AddRole
- AddPermission
- AddRoleUser
- CreatePlmApp
2. Update 相关方法:8个
- UpdateRole
- UpdatePermission
- UpdateResourceRiskLevel
- UpdatePlmAppManager
- UpdatePlmProductManager
- UpdateIndustryProductManager
- UpdateRoleMemberCapacity
- UpdateApproveStatus
3. Upsert 相关方法:6个
- UpsertRolePermission
- UpsertRoleUser
- UpsertRoleResource
- UpsertDutySchedule
- UpsertPlmPlatformRel
- UpsertIndustryPlatformRel
4. Del 相关方法:6个
- DelRole
- DelPermission
- DelRoleUser
- DelResource
- DelDutySchedule
- DeletePlmApp
初步思路
方案一:新增独立 Filter
- 实现方式:在 filter 包下创建一个新的 Filter,通过维护敏感词数组(如敏感资源名和操作类型)进行拦截判断。
- 流程:当请求命中敏感资源及操作时,异步记录操作日志到数据库,随后放行请求继续执行原逻辑。
- 问题:该方案可能导致一个请求被多个 Filter(日志 Filter 和敏感操作 Filter)重复拦截,造成资源浪费。
方案二:扩展原有 Log Filter
- 实现方式:在现有的 log Filter 中增加判断逻辑,若检测到请求涉及敏感资源的敏感操作,则将相关日志写入数据库。
- 优点:无需新增独立的拦截器,简化系统架构。
- 缺点:需要对原有 log Filter 的代码进行侵入性修改,可能增加维护复杂度。
目前优先考虑第一个方案,本地测试是可行的。
1 |
|
尝试调用 ListRole 接口,可以在控制台看到如下输出:
表设计
序号 | 字段名称 | 字段描述 | 数据类型 |
---|---|---|---|
1 | 操作人 | 记录执行操作的用户身份 | 文本类型 |
2 | 操作时间 | 记录操作发生的具体时间(需支持前端实现范围查询功能) | 日期时间类型 |
3 | 操作对象 | 指明被操作的目标实体(如用户、产品信息、产品族、产品树等) | 文本类型 |
4 | 操作类型 | 操作行为的分类(限定为以下枚举值:新增、修改、删除) | 枚举类型 |
5 | 操作内容 | 描述操作的具体行为(必须包含被操作对象的名称作为必填信息) | 文本类型 |
6 | 原始数据 | 记录操作执行前的原始状态数据(用于对比或回滚参考) | 文本类型 |
7 | 操作结果 | 记录操作执行的最终状态(如成功/失败/部分成功及具体结果说明) | 文本类型 |
8 | CreateTime | 审计字段 | 日期时间类型 |
9 | UpdateTime | 审计字段 | 日期时间类型 |
拦截项目中的敏感操作
http://example.com/2025/07/20/拦截项目中的敏感操作/