Iris 的 iris.JWT 在 v13+ 已移除,需改用 github.com/iris-contrib/middleware/jwt;直接导入旧版会报 undefined 错误,且密钥必须为 []byte、exp 字段不可缺、Authorization 头格式须严格为 Bearer 。

为什么 Iris 的 JWT 中间件不能直接用 iris.JWT?
因为 iris.JWT 是旧版(v12 之前)的内置函数,v13+ 已移除,官方推荐用社区维护的 iris-contrib/middleware/jwt。直接 import iris.JWT 会报 undefined: iris.JWT —— 这是新手最常卡住的第一步。
正确做法是:
- 运行
go get github.com/iris-contrib/middleware/jwt - 导入时用
"github.com/iris-contrib/middleware/jwt",不是"github.com/kataras/iris/v12/middleware/jwt"(路径错就找不到) - 注意:该包默认使用 HS256 算法,密钥必须是
[]byte,传字符串会 panic
如何配置 jwt.New 并处理 token 解析失败?
jwt.New 返回一个中间件,但它不会自动返回错误响应;token 失效、过期或签名错误时,ctx.Values().Get("jwt") 为 nil,但请求仍会往下走 —— 这容易导致后续 handler 意外 panic。
必须显式检查并中断流程:
authMiddleware := jwt.New(jwt.Config{
ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
return []byte("my-secret-key"), nil
},
SigningMethod: jwt.SigningMethodHS256,
})
<p>app.Use(authMiddleware)
app.Get("/profile", func(ctx iris.Context) {
user := ctx.Values().Get("jwt").(*jwt.Token) // 注意类型断言
if user == nil {
ctx.StatusCode(401)
ctx.JSON(iris.Map{"error": "invalid or expired token"})
return
}
ctx.JSON(iris.Map{"user_id": user.Claims.(jwt.MapClaims)["user_id"]})
})常见坑:
- 没做
user == nil判断,直接断言崩溃 -
Claims类型不是jwt.MapClaims,而是map[string]interface{},需先断言再取值 - 密钥长度太短(如
"abc")在某些 Go 版本下触发 crypto/hmac 错误
如何在登录接口生成带自定义字段的 token?
用 jwt.NewWithClaims 构造 token,再调用 token.SignedString。注意:claims 必须实现 jwt.Claims 接口,最简单是用 jwt.MapClaims。
示例登录 handler:
app.Post("/login", func(ctx iris.Context) {
var creds struct {
Username string `json:"username"`
Password string `json:"password"`
}
ctx.ReadJSON(&creds)
<pre class="brush:php;toolbar:false;">// 实际应查 DB + 密码校验
if creds.Username == "admin" && creds.Password == "123" {
claims := jwt.MapClaims{
"user_id": 123,
"role": "admin",
"exp": time.Now().Add(time.Hour * 24).Unix(), // 必须设 exp
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte("my-secret-key"))
if err != nil {
ctx.StatusCode(500)
ctx.JSON(iris.Map{"error": "token generation failed"})
return
}
ctx.JSON(iris.Map{"token": tokenString})
return
}
ctx.StatusCode(401)
ctx.JSON(iris.Map{"error": "invalid credentials"})})
关键点:
-
exp字段必须是int64(Unix 时间戳),传time.Time会解析失败 - 不要把敏感信息(如密码哈希)塞进 token,只放必要标识字段
- 前端需在请求头加
Authorization: Bearer <token></token>,否则中间件不识别
为什么 token 在 Postman 测试正常,但 Axios 请求 401?
大概率是请求头格式不对。Iris 的 JWT 中间件默认从 Authorization 头读 token,且严格匹配 Bearer <token></token> 格式(注意空格,注意大小写)。
Axios 常见错误写法:
-
headers: { Authorization: 'bearer xxx' }→bearer小写,中间件不认 -
headers: { Authorization: 'Bearerxxx' }→ 缺少空格,解析失败 -
headers: { token: 'xxx' }→ 完全没走 Authorization 头,中间件跳过
正确写法:
axios.get('/profile', {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
})调试建议:在中间件前后加日志,打印 ctx.Request().Header.Get("Authorization"),确认值是否符合预期。另外,CORS 配置遗漏也会导致预检请求失败,看似 401,实则是 403 或无响应。
密钥硬编码、exp 字段缺失、header 格式错位——这三个点,占了 JWT 集成问题的八成以上。其他逻辑都可后补,先确保这三处跑通,再加刷新、黑名单等高级功能。


















