iris 的 jwt 中间件仅解析校验 token,需手动完成提取、验证、绑定用户、拦截失败四步;配置时 extractor、validationkeygetter、signingmethod 必设,j.serve 必须前置路由 handler,失败时依赖 ctx.stopexecution() 阻断流程,用户状态校验和 ctx.user.set() 需业务代码实现。

Iris 本身不内置 JWT 认证逻辑,jwt 中间件只是帮你解析和校验 token 的工具,不是开箱即用的“登录即保护”方案;你必须自己处理提取、验证、绑定用户、拦截失败请求这四步,漏掉任一环都会导致鉴权失效。
怎么注册和配置 jwt 中间件
先安装:go get github.com/iris-contrib/middleware/jwt。配置核心是 jwt.Config,关键字段不能少:
-
Extractor:决定从哪取 token,常见值有jwt.FromHeader("Authorization")(默认读Authorization: Bearer xxx)或jwt.FromParameter("token")(读 URL 查询参数?token=xxx),别硬写成"auth"这种不存在的 header 名 -
ValidationKeyGetter:返回签名密钥,必须是func(*jwt.Token) (interface{}, error)类型,常见写法是直接返回[]byte("My Secret"),但生产环境应避免硬编码 -
SigningMethod:如jwt.SigningMethodHS256,必须和签发 token 时用的一致,否则ParseWithClaims直接报错 - 别漏掉
ContextKey(可选但推荐):设为"jwt"或自定义字符串,后续用ctx.Values().Get("jwt")取 token 更明确
j.Serve 路由挂载的正确姿势
j.Serve 是中间件 handler,必须放在路由 handler 前面,且不能包裹在 ctx.Next() 里——它自己就负责流程控制:
- 正确写法:
app.Get("/api/user", j.Serve, userHandler),j.Serve验证通过才进userHandler - 错误写法:在自定义中间件里调
j.Serve再手动ctx.Next(),会导致重复校验或跳过拦截 - 全局启用?可以,但慎用:
app.Use(j.Serve)会拦截所有路由,连/login都 401,得用app.Party("/api", j.Serve)分组更安全
验证失败后为什么还会执行业务逻辑
这是最常踩的坑:jwt 中间件内部遇到解析失败(签名错、过期、claim 格式不对)时,只调 ctx.StatusCode(401) + ctx.StopExecution(),但如果你在它之后又写了 ctx.Next(),或者没加 ctx.StopExecution(),后续 handler 仍会运行。
- 典型错误:在
userHandler开头写if token := ctx.Values().Get("jwt"); token == nil { ... }—— 这毫无意义,因为j.Serve已保证 token 存在且有效,这个判断既冗余又掩盖了中间件配置问题 - 真正该检查的是:token 解析后,
token.Claims里的用户 ID 是否在数据库存在、是否被禁用等业务逻辑,这部分必须在userHandler里做,不能塞进jwt.Config.ValidationKeyGetter - 调试技巧:在
j.Serve后加个日志中间件,看 401 响应后是否还打印 “in userHandler”,如果是,说明StopExecution()没生效或位置错了
如何把用户数据绑定到 ctx.User
jwt 中间件只负责解析 token 并存进 ctx.Values(),但 Iris 的 ctx.User.Get() 和 ctx.Login() 等方法依赖 ctx.User.Set() 显式绑定:
- 必须在验证通过后的某个环节调
ctx.User.Set(&user),其中&user是实现了iris.User接口的结构体(至少含ID() string方法) - 不能在
jwt.Config.ValidationKeyGetter里做这事——那个函数只返回密钥,没ctx参数 - 推荐做法:写一个独立中间件,放在
j.Serve后面,例如loadUser,里面取ctx.Values().Get("jwt"),解析出 user ID,查库,然后ctx.User.Set(&user) - 如果跳过这步,
ctx.User.Get()返回 nil,ctx.IsAuthenticated()始终 false,ctx.Logout()也无效
JWT 中间件真正的复杂点不在配置,而在「谁来决定用户是否合法」——jwt 只管签名和过期,用户状态(封禁、权限变更)必须由业务代码实时校验,且必须确保 ctx.StopExecution() 在所有失败路径上都被调用,没有例外。











