iris-contrib/middleware/jwt 默认配置易静默失败,需显式配置 extractor(如 jwt.fromheader)、validationkeygetter(返回 []byte)、signingmethod 一致,并确保中间件 j.serve 在路由链中前置注册,且取值前校验 ctx.values().get("jwt") 非空。

直接用 iris-contrib/middleware/jwt 就能跑通,但默认配置下容易因签名密钥不匹配、提取方式错位或上下文取值时机不对而静默失败——不是报错,而是跳过验证,导致未授权请求畅通无阻。
jwt.New 初始化时必须显式指定 Extractor 和 ValidationKeyGetter
Iris 的 JWT 中间件不会自动从 Authorization: Bearer xxx 提取 token,除非你明确告诉它怎么取。默认行为是尝试从 header,但若没配 Extractor,它可能退回到空逻辑,后续验证直接跳过。
-
Extractor: jwt.FromHeader("Authorization", "Bearer")是最常用写法,对应标准 header 格式 - 若用 URL 参数(比如调试时加
?token=xxx),得写jwt.FromParameter("token") -
ValidationKeyGetter必须返回[]byte,不能传字符串字面量;常见错误是写成return "My Secret", nil,这会导致签名验证永远失败 - 算法必须和签发时一致,比如签发用
jwt.SigningMethodHS256,这里也得设SigningMethod: jwt.SigningMethodHS256
中间件注册顺序决定是否生效
j.Serve 是一个 handler,不是“装饰器”,它必须出现在路由链中靠前位置,且在业务 handler 之前执行。如果把它放在后面,或者漏掉 ctx.Next() 类似逻辑(Iris 不需要手动调 Next,但顺序错就等于没挂上),认证就形同虚设。
- 正确写法:
app.Get("/secured", j.Serve, myAuthenticatedHandler) - 错误写法:
app.Get("/secured", myAuthenticatedHandler, j.Serve)—— 这时myAuthenticatedHandler已经执行完了,j.Serve根本没机会拦截 - 全局注册也一样:
app.Use(j.Serve)要在app.Get(...)之前调用,否则对已注册的路由无效
ctx.Values().Get("jwt") 取值前必须确认验证已通过
中间件只在验证成功时才往 ctx.Values() 写入 *jwt.Token。如果 token 过期、签名错误或提取失败,这个 key 根本不存在,直接 .Get("jwt").(*jwt.Token) 会 panic。
- 安全做法:先判空再断言,例如
v := ctx.Values().Get("jwt"); if v == nil { ctx.StatusCode(401); return } - 不要假设
user.Claims一定是jwt.MapClaims,它可能是map[string]interface{}或其他结构,取决于签发时传的 claims 类型 - 建议在 handler 开头加日志:打印
token.Valid和token.Method.Alg(),快速定位是过期、算法不匹配还是密钥错误
最容易被忽略的是密钥一致性:签发 token 用的 secret 和验证时 ValidationKeyGetter 返回的 secret 必须完全相同(包括空格、大小写、换行),且不能硬编码在多个地方——一旦改一处漏一处,整个认证链就断了。











