必须调用 ctx.StopExecution() 才能真正拦截请求,否则即使设了 401 状态和 JSON 响应,后续 handler 仍会执行;取 Authorization 头需先校验 "Bearer " 前缀再截取 token。

中间件里不调 ctx.StopExecution() 就等于没拦截
很多开发者写了 JWT 校验逻辑,也设了 ctx.StatusCode(iris.StatusUnauthorized) 和 ctx.JSON(),但请求还是进了业务 handler。根本原因是 Iris 不会自动中断执行链——ctx.Next() 仍会继续往下走。必须在写完响应后立刻调用 ctx.StopExecution()(ctx.Abort() 在 Iris 里不存在,别搜错了)。漏掉这一步,轻则返回两次响应触发 http: superfluous response.WriteHeader panic,重则未授权用户直接操作数据库。
- 错误模式:
ctx.StatusCode(401); ctx.JSON(...); ctx.Next()→ handler 照常执行 - 正确模式:
ctx.StatusCode(401); ctx.JSON(...); ctx.StopExecution()→ 后续全跳过 - 别依赖
return:即使写了return,没调StopExecution,下一个中间件或 handler 仍可能被执行
从 Authorization 头取 token 必须校验前缀和空值
ctx.GetHeader("Authorization") 返回的是完整字符串,比如 "Bearer eyJhb..." 或 "" 或 "Basic abc"。直接 strings.Split(header, " ")[1] 会 panic 或取错值。
- 先检查是否以
"Bearer "开头(注意末尾空格):strings.HasPrefix(header, "Bearer ") - 再安全截取:
tokenString := strings.TrimPrefix(header, "Bearer ") - 如果
tokenString == ""或长度 ctx.StopExecution() - 不要用
ctx.GetHeader()替代ctx.Request().Header.Get()——后者更底层、更可靠
JWT 解析必须验证签名、过期、Issuer,不能只看 Valid 字段
Iris 不封装任何 JWT 逻辑,全靠你手动调 jwt.ParseWithClaims()。常见疏漏是只检查 token.Valid,却忽略 claims.ExpiresAt.Time.After(time.Now()) 或 claims.Issuer == "my-app",导致过期 token 或伪造 issuer 的请求被放行。
- 密钥必须从配置读取,禁止硬编码:
config.JWTSecret - 用
jwt.ParseWithClaims(tokenString, &MyClaims{}, func(t *jwt.Token) (interface{}, error) { ... })显式传入 claims 类型和密钥函数 - 解析成功后,必须手动校验
claims.ExpiresAt、claims.IssuedAt、claims.Issuer等字段 - 验证通过后,建议用
ctx.Values().Set("user", user)透传用户信息,下游 handler 再取,避免重复查库
注册位置决定拦截范围,别只挂在一个路由上
把鉴权中间件只写在 app.Get("/api/user", authMiddleware, handler) 里,其他同组接口(比如 /api/order)就完全绕过了。权限控制必须统一注册,否则策略失效。
- 全局拦截:
app.Use(authMiddleware)—— 注意它也会作用于/favicon.ico、/health等路径,中间件内要用ctx.Path()跳过免检路径 - 精准拦截:
api := app.Party("/api"); api.Use(authMiddleware)—— 推荐方式,只约束子路径 - 别把中间件塞进某个 handler 函数体里,那不是中间件,只是普通条件判断
- 多个中间件顺序重要:
app.Use(a, b, c)表示 a → b → c → handler,越靠前的越先执行
最易被忽略的是:JWT 密钥不一致、服务器时间偏差超过几分钟、或前端发错 header(比如漏了 Bearer 空格),都会导致解析失败但错误提示模糊。上线前务必用真实 token 在日志里确认 jwt.ParseWithClaims 的第二个返回值 error 是否为 nil。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











