JWT中间件需通过app.Party("/api").Use(jwtMiddleware)注册以隔离保护路由;登录成功后用jwt.NewToken+Sign生成含user_id和exp时间戳的token并JSON返回;handler中通过ctx.Values().Get("jwt")断言解析获取用户信息;登出依赖前端清除,刷新需签发新token并可选Redis管理旧jti。

JWT 中间件怎么注册到 Iris 路由链里
Iris 本身不内置 JWT 支持,得靠 iris-contrib/middleware/jwt 这个官方维护的扩展包。注册时不能直接用 Use 全局挂载,否则所有路由(包括登录接口)都会被拦截——用户连登录都进不来。
实操建议:
- 用
app.Party("/api").Use(jwtMiddleware)隔离受保护路由前缀,登录、注册等公开接口走根 Party 或单独定义 -
jwtMiddleware初始化时必须传入有效的Secret和Extractor;默认只从Authorization: Bearer <token>提取,如果前端放 header 名是X-Auth-Token,就得自定义Extractor函数 - 别漏掉
Config.SigningMethod,Iris 默认用HS256,但如果你后端签发时用了RS256,这里不匹配就会报token is invalid
怎么在登录成功后生成并返回 JWT
登录逻辑跑通后,调用 jwt.NewToken 构造 token,再用 token.Sign 签名。关键不是“怎么生成”,而是“哪些字段该塞进去”和“怎么安全返回”。
常见错误现象:前端拿不到 token、token 解析后没用户 ID、过期时间不起作用。
实操建议:
-
Claims至少包含jwt.MapClaims{"user_id": 123, "exp": time.Now().Add(24 * time.Hour).Unix()};exp必须是 int64 时间戳,不是 duration - 别把密码、敏感权限字段直接写进 payload——JWT 是 Base64 编码(非加密),客户端可解码查看
- 返回时用
ctx.JSON(iris.Map{"token": tokenString}),不要放在 cookie 里(除非明确配了HttpOnly+Secure)
如何在 handler 里读取解析后的用户信息
中间件验证通过后,用户数据存在 ctx.Values().Get("jwt"),但这个值是 *jwt.Token 类型,不是 map。直接强转 map[string]interface{} 会 panic。
使用场景:获取当前登录用户 ID 去查数据库、做权限判断、记录操作日志。
实操建议:
- 先断言:
if token, ok := ctx.Values().Get("jwt").(*jwt.Token); ok { ... } - 再取 claims:
claims := token.Claims.(jwt.MapClaims),然后userID := int64(claims["user_id"].(float64))—— 注意 JSON number 默认是 float64,要手动转 - 别依赖
ctx.User(),Iris 的User是另一套 session 机制,和 JWT 中间件无关
刷新 token 和登出怎么处理
JWT 本身无状态,服务端无法主动“作废”一个已签发的 token。所谓“登出”,其实是前端清空本地存储;所谓“刷新”,本质是发新 token 换旧 token。
性能 / 兼容性影响:频繁刷新会增加签名开销,且需额外维护 refresh token 的白名单或 Redis 过期 key,否则无法阻止旧 token 继续使用。
实操建议:
- 刷新接口(如
POST /auth/refresh)应校验原 token 的exp是否临近过期,并签发新 token,同时可选地把旧jti记入 Redis 设置短过期(比如 30 分钟) - 登出接口无需服务端动作,但若你做了 refresh token 白名单,记得在此接口中调用
redis.Del("rt:" + jti) - 别在刷新时延长原 token 的
exp,JWT 不支持 inplace 更新;必须签发全新 token 字符串
实际最难的不是签 token,是设计好 token 生命周期策略和配套的 refresh/revocation 边界逻辑——这些没法靠中间件自动完成,得你根据业务权衡。


















