中间件函数签名必须为func(ctx iris.Context),调用ctx.Next()才能继续执行;需显式注册到Party分组,通过ctx.Values()传递数据;OPTIONS预检请求需单独注册路由或处理,中间件执行顺序依赖Use调用位置与Party嵌套层级。

中间件函数签名必须匹配 iris.Handler
自定义中间件本质就是一个接受 iris.Context 参数、无返回值的函数,类型必须是 iris.Handler。写成 func(iris.Context) error 或 func(*context.Context) 都会编译失败或运行时 panic。
常见错误现象是 IDE 提示类型不匹配,或者启动时报 cannot use xxx (type func(iris.Context)) as type iris.Handler。
- 正确写法:
func(ctx iris.Context) { ... } - 必须调用
ctx.Next()才能让请求继续向下执行(比如进到路由处理器) - 若在中间件中提前调用
ctx.StopExecution()或ctx.StatusCode(401)+ctx.WriteString(),后续中间件和 handler 就不会执行
如何在路由组中注册自定义中间件
Iris 不支持全局自动注入中间件(不像某些框架的 app.UseAll()),必须显式绑定到具体路由或路由组。最常用的是 Party 分组 + Use。
典型场景:给 /api/v1 下所有接口加日志+鉴权,但 /health 和 /swagger 排除。
- 用
app.Party("/api/v1")创建子路由器,再对其调用.Use(yourMiddleware) - 排除路径要靠中间件内部逻辑判断,比如检查
ctx.Path()是否包含"health",然后跳过ctx.Next() - 不要试图在
app.Use()里注册后又想局部禁用——Iris 没有中间件开关机制,只能靠中间件自己条件跳过
中间件里读取和修改请求上下文数据
Iris 的 iris.Context 提供了 Values 映射,是中间件之间传递数据的主要方式,比用闭包捕获变量更安全、更符合生命周期预期。
容易踩的坑是误用 ctx.Params()(只存路径参数)或 ctx.Request().URL.Query()(需手动解析),结果读不到上游中间件塞进去的值。
- 写入:
ctx.Values().Set("user_id", 123) - 读取:
uid := ctx.Values().GetInt64("user_id"),注意类型断言失败会返回零值 - 不要往
ctx.Request().Context()里塞东西——Iris 不读取它,且可能被 HTTP/2 流复用干扰 -
ctx.Values()是 per-request 生命周期,无需手动清理
为什么 OPTIONS 预检请求常绕过你的中间件
如果你的自定义中间件没对 OPTIONS 方法生效,大概率是因为没在路由表中注册对应路径的 OPTIONS 处理器。Iris 不会为未注册的 method 自动触发中间件。
例如你写了 app.Use(authMiddleware),但前端发来预检请求到 /api/login,而你只注册了 app.Post("/api/login", ...),那这个 OPTIONS 请求根本不会进到 authMiddleware 里。
- 解决办法:显式注册通配
OPTIONS路由,如app.Options("/api/*", corsMiddleware) - 或者在中间件开头加判断:
if ctx.Method() == "OPTIONS" { ctx.StatusCode(204); return },但前提是该路径已注册OPTIONShandler - 别依赖 “中间件先于路由匹配” —— Iris 是先匹配路由,再执行其绑定的中间件链
实际开发中最容易被忽略的是中间件执行顺序与路由注册时机的耦合关系:Use 调用位置决定它作用于哪些路由,而 Party 的嵌套层级决定了中间件是否继承。写错一层,整个认证或日志就失效。











