认证中间件必须调用ctx.StopExecution()阻断后续流程,否则校验失败后仍会执行handler;应配合ctx.StatusCode(401)和ctx.JSON()返回错误,并确保ctx.Next()仅在验证通过时调用。

认证中间件必须调用 ctx.StopExecution() 阻断后续流程
很多开发者写完 JWT 或 Session 校验逻辑后,发现认证失败仍继续执行 handler,根本原因是没显式终止请求链。Iris 的中间件是洋葱模型,ctx.Next() 才往下走,但校验失败时你得主动喊停。
- 如果校验不通过,直接
ctx.StatusCode(iris.StatusUnauthorized)+ctx.StopExecution(),否则ctx.Next()会继续调用下一个 handler - 不要只写
ctx.WriteString("unauthorized")就返回——Iris 不会自动中断,后续代码照常执行,可能造成数据泄露或重复响应 - 常见错误现象:
http: multiple response.WriteHeader calls,就是校验失败写了响应,又进到业务 handler 再写一次
app.Use() 和 app.UseRouter() 的作用范围差异
全局认证中间件通常用 app.Use(),但它不拦截静态文件、模板渲染等内部路由;若需对所有 HTTP 流量(包括 /public/*、/favicon.ico)都做校验,得改用 app.UseRouter()。
-
app.Use():只作用于注册的路由(即app.Get()、app.Post()等定义的路径) -
app.UseRouter():在路由器匹配前执行,能拦截所有入站请求,包括未注册路径和静态资源 - 性能影响:用
UseRouter会多一次函数调用开销,但对认证这类必需前置检查是合理代价
Token 解析后如何安全存入 Context 并透传
别把用户 ID 或权限直接塞进 ctx.Values().Set() 后就不管了——Iris 的 ctx.Values() 是 request-scoped,但容易被下游中间件意外覆盖或误读。
- 推荐用强类型 key:定义
type ctxKey string; const userCtxKey ctxKey = "user",再ctx.Values().Set(userCtxKey, user) - 下游 handler 中必须用同个 key 取值:
u := ctx.Values().Get(userCtxKey),避免字符串拼错导致 nil panic - 切勿在中间件里修改
ctx.Request().Header来“伪造”身份,Header 可被客户端篡改,必须依赖已验证的上下文值
Cookie 认证中间件中 DisableBodyConsumptionOnUnmarshal 的坑
如果你用 Cookie 存 token 并在中间件里调用 ctx.ReadJSON() 或 ctx.UnmarshalBody() 解析登录参数,注意全局配置 DisableBodyConsumptionOnUnmarshal 默认为 false —— 这会导致 body 被读取一次后无法复用。
- 认证中间件若提前读了 body(比如解析登录表单),业务 handler 再读就会得到空数据
- 解决方案一:在认证中间件中避免读 body,只从 Header 或 Cookie 提取 token
- 解决方案二:如必须读 body,启动时显式关闭该限制:
iris.WithConfiguration(iris.Configuration{DisableBodyConsumptionOnUnmarshal: true}),但要清楚这会让多次ReadJSON调用都有效(底层会缓存 body)


















