Skip to content

4.8 横切机制 ​

概述

横切关注点不在业务代码中重复出现——认证、租户、日志、审计、软删分别由中间件链与 GORM 全局钩子在固定位置统一执行。本页给出"每个红线由谁执行"的总图。

红线执行点总览 ​

红线执行点时机
统一信封 + panic 恢复Response 中间件响应写出时
身份认证JWT 中间件请求进入业务前
租户上下文Tenant 中间件 + Scope请求级 + SQL 级
权限校验Authz 中间件(元数据驱动)handler 前
操作日志OperationLog 中间件请求结束后异步
限流RateLimit 中间件认证前
审计字段盖章GORM create/update 钩子写 SQL 前
物理删除拦截GORM delete 钩子删除 SQL 前
软删过滤repository Scope(ApplyCtx)查询构建时

审计盖章(createStamp / updateStamp) ​

text
Insert 前:补 create_user / create_time / del_flag=0 / tenant_id(租户表)
Update 前:盖 update_user / update_time

业务代码永不手工赋值审计列——这是钩子存在的意义。create_user/update_user 从 ctx 身份取。

物理删除拦截(blockPhysicalDelete) ​

一切物理 DELETE 默认被拒绝。确需物理清理的场景(如 LogClean 任务清超期日志):

go
ctx = hooks.WithPhysicalDelete(ctx)   // 显式放行,作用域仅此 ctx 链路

查询侧 Scope(ApplyCtx) ​

repository.Ctx(ctx) 在 SQL 构建前以 GORM Scope 注入:

text
所有表:        del_flag = 0
租户白名单表:   非平台级身份追加 tenant_id IN (0, 自身租户)

租户判定依据 hooks.tenantTables 白名单(9 张表)——新增租户级表必须同步登记。

身份与上下文的流动 ​

text
JWT 中间件   解析 Token → ctx 写入用户身份(loader 经 init 接线)
Tenant 中间件 加载租户 → ctx 写入租户身份
    ↓
service / repository / 钩子 从 ctx 读身份(盖章、隔离、日志)

ctx 是横切数据的唯一载体——不使用全局变量传递请求态数据。

日志的三个层次 ​

层次载体内容
运行日志zap(log/ 目录)排查用,带 trace_id
操作日志gin_operation_log 表审计用,谁在何时对什么做了什么
登录日志gin_login_log 表登录行为专项

操作日志的采集内容由 RouteSpec 声明驱动(Log/LogType),异步落库不阻塞响应。

演示模式(Demo 中间件) ​

app.demo=true 时写操作一律拒绝,读操作与登录类公开接口放行——演示环境保护数据的同时不影响体验。

横切的可裁剪性 ​

WireCheck 保证接线缺失只降级不崩:去掉 auth 模块则身份扩展加载跳过,去掉 operation_log 则日志丢弃。裁剪部署形态由启动告警明确提示。

下一步 ​

→ 4.9 缓存架构设计

小蚂蚁云团队 · 提供技术支持