Iris 官方不内置 JWT 支持,需手动集成 github.com/golang-jwt/jwt/v5 等第三方库,编写符合 iris.Handler 签名的中间件,完成 Authorization 头解析、token 校验(含签名、过期、算法匹配)及用户信息注入 ctx.Values(),错误时调用 ctx.StopWithStatus(401),成功后放行 ctx.Next()。

怎么在 Iris 中注册 JWT 验证中间件
直接用 iris.JWT 是错的——Iris 官方不内置 JWT 支持,所谓 “iris.JWT” 实际是旧版文档残留或社区误传。你得自己集成第三方库(比如 github.com/golang-jwt/jwt/v5),再写一个符合 iris.Handler 签名的中间件函数。
关键不是“调个函数”,而是把 JWT 解析、校验、用户信息注入上下文这三步串起来,并确保错误时能统一拦截响应。
- 推荐用
github.com/golang-jwt/jwt/v5(v5 起默认禁用弱算法,更安全) - 密钥必须从环境变量或配置读取,别硬编码在代码里
- 中间件要返回
ctx.Next()(放行)或ctx.StopWithStatus(401)(拒绝),不能只写return - 别在中间件里做数据库查用户——JWT payload 里应已含必要字段(如
user_id、role),查库逻辑放到业务 handler 里按需触发
如何解析 Authorization Header 并校验 token
JWT 通常放在 Authorization: Bearer <token></token> 头里,但很多人漏掉前缀检查或空值处理,导致 panic 或静默失败。
校验环节最容易出问题的是:算法不匹配、过期时间未验证、签名校验失败却没返回具体原因。
- 用
strings.HasPrefix(ctx.GetHeader("Authorization"), "Bearer ")判断头是否存在且格式正确 - 提取 token 后,用
jwt.ParseWithClaims(tokenString, &MyClaims{}, keyFunc),其中keyFunc必须返回*rsa.PrivateKey或[]byte,不能返回 nil - 显式检查
err != nil和token.Valid == false两种情况,前者可能是解析失败(如 base64 错误),后者才是签名校验/过期等业务错误 - 过期错误(
*jwt.TokenExpiredError)建议返回401,而非403;签名错误一律401
怎么把用户信息塞进 ctx 并在 handler 里安全读取
Iris 的 ctx.Values() 是请求生命周期内的内存存储,适合放解析后的用户数据,但要注意类型断言安全和 key 命名冲突。
别用字符串字面量当 key(比如 "user"),多个中间件可能覆盖;也别直接存原始 *jwt.Token,它不含业务字段。
- 定义常量 key:
const CtxUserIDKey = "user_id",然后ctx.Values().Set(CtxUserIDKey, claims.UserID) - 在业务 handler 里用
id, ok := ctx.Values().Get(CtxUserIDKey).(int64),必须检查ok,否则 panic - 如果需要更多字段(如 role、email),建议封装成结构体再存:
ctx.Values().Set(CtxUserKey, MyUser{ID: claims.UserID, Role: claims.Role}) - 不要在中间件里调
ctx.User()——那是 Iris 内置 auth,和 JWT 无关,用了反而混淆逻辑
为什么登录接口返回 token 后,后续请求仍 401
这不是中间件写错了,大概率是客户端没正确传 token,或服务端密钥/算法不一致。JWT 是无状态的,服务端不会“记住”这个 token,每次都要完整校验。
常见盲区:前端 localStorage 存了 token,但 fetch 请求没带 header;或者后端生成 token 时用了 SigningMethodHS256,而中间件校验时用了 SigningMethodRS256。
- 登录接口生成 token 时,用
jwt.NewWithClaims(signingMethod, claims),确保signingMethod和中间件里keyFunc返回的密钥类型匹配 - 用 curl 测试最可靠:
curl -H "Authorization: Bearer ey..." http://localhost:8080/api/profile - 中间件开头加一行
iris.Logger().Infof("Auth header: %s", ctx.GetHeader("Authorization")),确认 header 真的到了 - 如果用 Postman,检查是否启用了 “Automatically persist cookies” 类似选项——JWT 不依赖 cookie,这个开关无关
JWT 的密钥管理、算法选择、payload 设计这些环节,比中间件代码本身更容易出问题。写完中间件只是第一步,重点得盯住 token 生成与消费两端是否对得上。


















