Iris 的 jwt.New() 默认只解析不验证签名,需显式调用 .Serve() 并传入验证配置;密钥类型/长度须与签发一致;签发时用 SignString/SignBytes 并设置 exp/iss;Verify 中间件默认从 Authorization: Bearer 提取 token。

为什么 Iris 的 jwt.New 默认不校验签名?
直接用 jwt.New() 创建中间件时,请求能通过但 ctx.UserValue("user") 总是 nil,常见于没显式启用验证逻辑。Iris 的 JWT 中间件默认只解析 token,不自动验证签名、过期或签发者——必须手动调用 .Serve 并传入验证配置。
- 必须显式调用
middleware.Serve(),否则中间件不生效 - 签名密钥必须与签发时完全一致(类型、长度、编码方式),
string和[]byte混用会导致验证失败 - 若使用
HS256,密钥长度建议 ≥ 32 字节;用RS256则需确保公钥 PEM 格式正确且无多余空格
如何正确签发带 exp 和 iss 的 token?
前端传来的登录凭据验证通过后,签发 token 时若漏掉关键声明(claims),后续校验会失败。Iris 自带的 jwt.Token 不强制要求字段,但验证中间件默认检查 exp(过期)和 iss(签发者),除非你显式禁用。
- 用
jwt.Token{ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), Issuer: "myapp"}显式设置 - 签发时务必用
token.SignString(key)或token.SignBytes(key),别用token.String()(它不签名) - 返回给前端时,建议统一放在
Authorization: Bearer <token></token>头里,而非自定义字段
jwt.Verify 中间件为何总返回 401?
常见错误不是密钥不对,而是 token 提取方式不匹配。Iris 的 jwt.Verify 默认从 Authorization 头按 Bearer xxx 解析,如果前端传的是 Token xxx 或放 body 里,中间件根本读不到 token。
- 确认前端请求头是
Authorization: Bearer eyJhbGciOiJIUzI1NiIsIn... - 如需从 cookie 读取,得自己写提取逻辑:
token := ctx.Cookies().GetString("jwt"),再手动调用parser.Parse(token) - 调试时加一行
ctx.Application().Logger().Infof("raw token: %s", ctx.GetHeader("Authorization"))看实际拿到什么 - 注意时区:服务器时间若比客户端快,
exp可能已过期,用time.Now().UTC().Unix()统一时区
如何在 handler 中安全获取用户 ID?
中间件验证成功后,用户信息存在 ctx.UserValue("jwt"),但它是 jwt.Token 类型,不是原始 map。直接类型断言成 map[string]interface{} 会 panic,必须用结构体或 token.Get 方法取值。
- 推荐定义结构体:
type Claims struct { jwt.StandardClaims; UserID uint `json:"user_id"` } - 在 handler 中:
v := ctx.UserValue("jwt"); if token, ok := v.(*jwt.Token); ok { claims := Claims{}; token.Claims(&claims) } - 别依赖
ctx.Values().Get("user_id")—— Iris 的 JWT 中间件默认不自动注入这些键,要自己 set - 敏感操作前,再次检查
claims.UserID > 0,防止伪造 token 带空值绕过
最易被忽略的是:Iris 的 jwt 包底层用的是 github.com/golang-jwt/jwt/v5,但它的 Parse 方法默认不校验 exp,必须显式传 jwt.WithValidMethods 和 jwt.WithExpirationRequired —— 而 Iris 的 Verify 中间件封装时已经做了,前提是你的配置没覆盖掉这些选项。


















