Iris中间件必须显式注册且严格按顺序挂载,app.Use仅影响其后路由,权限中间件需用Party分组隔离,CORS需配合显式OPTIONS路由,静态缓存和链路追踪依赖注册位置,所有中间件无默认行为。

直接装完 iris 后不能“开箱即用”中间件——它不会自动注册、不按名称加载、也不隐式生效,所有中间件都必须显式挂载到具体作用域(全局、分组或单个路由),且顺序决定执行链是否完整。
中间件必须显式注册,app.Use 不等于“全局启用”
app.Use 只影响它之后注册的路由,不是“全站拦截”。比如你先写 app.Get("/health", healthHandler),再写 app.Use(authMiddleware),那 /health 根本不会经过鉴权中间件。
- 想让中间件覆盖全部路由,必须把
app.Use(...)放在所有app.Get/app.Post之前 - 但即便如此,它仍不处理未注册的
OPTIONS请求(跨域预检会 404) -
app.UseRouter是另一个选项,只作用于当前路由器及其子路由,适合模块隔离 - 别在
app.Use里调用panic或log.Fatal,这会让整个服务崩溃;要用recover.New()这类专用恢复中间件
Party 分组 + Use 是权限类中间件唯一安全用法
权限中间件绝不能全局注册,否则会拦掉 /health、/favicon.ico、静态资源等非业务路径,导致健康检查失败或前端白屏。
- 正确姿势是:用
admin := app.Party("/admin")创建分组,再admin.Use(AuthMiddleware("admin")) - 确保
OPTIONS预检路由在权限中间件前注册,例如admin.Options("/*path", corsHandler)或app.Any("/admin/*path", corsHandler) - 中间件内部必须显式校验角色,不能只存
ctx.User.Set(&user)就完事——那只是传值,不是放行 - 校验失败时,必须调用
ctx.StatusCode(403)+ctx.StopExecution(),否则请求还会往下走
CORS 中间件必须配合显式 OPTIONS 路由才能生效
只写 app.Use(corsMiddleware) 是无效的。Iris 不会为未注册的 HTTP 方法创建路由,浏览器发来的预检 OPTIONS 请求压根进不了中间件链,直接返回 404。
- 要么对每个 API 前缀补
app.Options("/api/*", corsHandler) - 要么用更通用的
app.Any("/*path", corsHandler)捕获所有方法(含 OPTIONS) - 预检响应里必须设全关键头:
Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-Control-Max-Age - 如果前端带
credentials: 'include',Access-Control-Allow-Origin就不能是"*",得动态匹配白名单中的Origin头
静态缓存、日志、链路追踪等中间件要注意作用域和时机
像 iris.StaticCache、自定义 trace 注入、请求体日志这类中间件,非常依赖注册位置和执行顺序。
-
iris.StaticCache(24 * time.Hour)只对app.HandleDir()等 Iris 原生静态服务响应生效,对app.Get("/file", handler)返回的文件无效 - 静态缓存中间件若被其他中间件(如 CORS 或安全头设置)后置覆盖,
Cache-Control就会丢失——把它放在app.Use链最前面通常更稳 - 链路追踪中间件必须从
traceparent或X-Trace-ID解析 ID 并存入ctx.Values(),下游 HTTP/gRPC 调用时再手动注入,Iris 不自动透传 - 切勿在中间件里提前读
ctx.ReadBody(),会消耗 request body 流,导致后续 handler 的ctx.ReadJSON()失败
真正容易被忽略的是:中间件的“生效范围”和“执行时机”完全由你注册的位置和方式决定,没有魔法,也没有默认行为。一个 ctx.Next() 忘了写,整条链就断了;一个 OPTIONS 路由漏注册,跨域就卡死;一次 ctx.ReadBody() 提前调用,API 就开始静默失败。

















