中间件注册顺序决定执行时机,必须显式注册且按序执行;ctx.next()是显式放行开关,非自动跳转;全局、分组、单路由中间件注册方式不同;鉴权需校验通过才调ctx.next(),否则stopexecution;ctx.user需手动set;options预检须单独注册路由。

中间件注册顺序决定执行时机
中间件不是“写了就能用”,必须显式注册到对应路由或分组上,且顺序直接影响逻辑流。Iris 按注册顺序依次执行中间件,ctx.Next() 是手动触发后续 handler 的开关,不是自动跳转。
- 全局中间件用
app.Use(),对所有路由生效,优先级最高 - 分组中间件必须注册在
Party实例上,比如admin.Use(authMiddleware),只影响/admin/*下的路由 - 单个路由可传多个中间件:
app.Get("/user", auth, log, handler),从左到右执行 - 如果某个中间件里没调
ctx.Next(),后续所有 handler(包括其他中间件和业务逻辑)都不会执行
ctx.Next() 不是“继续执行”,而是“显式放行”
ctx.Next() 是 Iris 中间件链的关键控制点,它不带条件、不自动判断,只是把控制权交给下一个 handler。很多鉴权失败后仍进业务逻辑,就是误以为 ctx.Next() 会跳过非法请求。
- 正确写法是:校验通过才调
ctx.Next(),否则立刻ctx.StopExecution()或ctx.StopWithStatus(401) - 别在中间件末尾无条件写
ctx.Next(),这等于默认放行所有请求 - 错误示例:
if !valid { ctx.StatusCode(401); return }; ctx.Next()——return后ctx.Next()根本不会执行,但很多人会漏掉return导致逻辑穿透
ctx.User.Set() 必须在中间件里手动调用
Iris 的 ctx.User 是空接口,不会自动识别 session 或 JWT 状态。登录态要靠你在中间件里主动绑定,否则 ctx.User.Get() 始终返回 nil。
- JWT 场景:解析 token 成功后,构造用户结构体(需实现
iris.User接口),再调ctx.User.Set(&user) - Session 场景:每次请求从
ctx.Session().Get("user_id")查 ID → 查库 → 构造用户 →ctx.User.Set(&user) - 别依赖
ctx.Login(user)就完事——它只是快捷封装,底层仍是ctx.User.Set(),且要求user实现了GetID()等方法
OPTIONS 预检请求必须单独注册路由
Iris 不会自动捕获或响应 OPTIONS 请求,哪怕你写了 CORS 中间件,若没注册对应路径的 OPTIONS handler,预检就直接 404,前端报错 “preflight request doesn't pass access control check”。
- 必须显式调用
app.Options("*", corsHandler)或按路径注册,如api.Options("/users", corsHandler) -
corsHandler里只需ctx.StatusCode(204)并设置必要头,不用ctx.Next() - 中间件里判断
ctx.Method() == "OPTIONS"是无效的——路由不匹配,中间件根本不会运行 - 生产环境禁用
Access-Control-Allow-Origin: "*"+credentials: true组合,浏览器直接拦截
ctx.Next()、每一次 ctx.StopExecution()、每一次 ctx.User.Set(),都得你亲手写清楚。











