# F. 中间件执行顺序 :::tip 概述 七层中间件 + Bind 包装层的完整执行顺序与短路行为速查。注册顺序即执行顺序(router.go s.Use)。机制详解见 [4.2 请求处理链路](../architecture/request-flow)。 ::: ## 执行顺序总表 | # | 中间件 | 文件 | 职责 | 短路 | |---|--------|------|------|------| | 1 | CORS | cors.go | 跨域头/预检 | OPTIONS 204 | | 2 | Response | response.go | 元信息入 ctx;SVG 加固;panic 兜底 | panic→500 | | 3 | RateLimit | ratelimit.go | 固定窗口限流(IP+路径) | 429 | | 4 | Demo | demo.go | 演示模式拦截写操作 | 1015 | | 5 | JWT | jwt.go | 令牌校验;身份注入(缓存 300s) | 401 | | 6 | Tenant | tenant.go | 租户状态/过期(缓存 60s) | 1005/1006 | | 7 | OperationLog | operation_log.go | 日志采集(不短路,异步落库) | — | | 8 | Bind 包装层 | router/bind.go | 权限校验 → 参数解析(gvalid) → 分发 → 信封 | 403/400 | ## 请求生命周期(12 步) ```text 1 CORS 预检/头设置 2 Response 元信息入 ctx;defer panic 兜底 3 RateLimit 固定窗口计数,超限 429 4 Demo 演示模式拦截写操作 5 JWT Parse+黑名单 → 注入身份(Roles/Perms/DataScope/DeptId) 6 Tenant 租户状态/过期校验(60s 缓存) 7 OperationLog 记 start,Next() 8 Bind 包装层 元数据入 ctx → HasPerm(403) → Parse(400) → 调 controller 9 controller 转发 service 接口 10 logic ModuleSpec 流水线;dao.Ctx 查询 11 response.Write 信封写出(code/body 记入 ctx) 12 OperationLog 组装 entry → 异步通道 → 批量落库 ``` ## 公开路径(跳过 5/6/7 的认证依赖) ```text publicPaths(精确匹配): /api/login · /api/register(放行但路由未注册)· /api/captcha /api/oauth2/token · /api/health 另放行:/api.json · /swagger* 三处一致:middleware/public.go / gmeta public:"true" / router.go 手工注册 ``` ## 依赖接线(wire.go 三函数变量) ```text IdentityLoader 由 logic/auth.go init 注册(LoadIdentity) TenantLoader 由 logic/auth.go init 注册(LoadTenant) LogSink 由 logic/operation_log.go init 注册(SaveOperationLog) cmd/wire.go 启动期检查非 nil(缺失告警不阻断) ``` ## 新增中间件检查项 ```text □ 职责单一;读配置用 cfgBool/cfgInt;IP 用 realClientIP □ 不 import 业务包(需要业务数据走 wire.go Loader) □ s.Use 链按序插入(顺序即语义,评审明确插入点) □ 确认对 IsPublicPath 的放行策略 □ 更新本速查与 4.2 文档 ```