Beego中JWT认证核心是登录生成token和请求时解析校验:登录接口用jwt.StandardClaims或自定义结构体(含ExpiresAt)、HS256签名及一致密钥生成token;BaseController中ParseToken从Authorization header提取Bearer token,用相同密钥和结构体解析并校验token.Valid与claims有效性,成功后存用户信息至c.Data供后续使用。

Beego 里用 JWT 做认证,核心就两件事:登录时生成 token,后续请求时解析并校验 token。别被“鉴权”“中间件”“拦截器”这些词绕晕——实际就是写两个函数,一个塞进 BaseController,一个在登录接口里调。
登录成功后怎么生成 JWT token
生成 token 的关键不是加密算法,而是 payload 结构和签名密钥的一致性。用 jwt.StandardClaims 或自定义结构体都行,但必须包含 ExpiresAt(否则 ParseWithClaims 默认会报 token is expired 错误)。
-
SigningMethodHS256最常用,密钥用字符串转[]byte即可,比如[]byte("my-secret-key") - payload 中建议至少带
UserID和Username,避免每次还要查库;不要放敏感字段(如密码、手机号) - 过期时间别硬写死,用
time.Now().Add(time.Second * time.Duration(expireSeconds)).Unix()动态算 - 生成失败时,
token.SignedString返回的err通常是密钥为空或结构体字段没导出(首字母小写)
如何在 BaseController 里统一校验 Authorization header
Beego 没有内置 JWT 中间件,得自己在 BaseController 的 Prepare 方法里手动解析。重点不是“拦截”,而是“拿到 header 后怎么安全地解 token”。
- 先从
c.Ctx.Input.Header("Authorization")取值,格式必须是"Bearer xxx",空格不能少,否则strings.Split会越界 - 用
jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyFunc),其中keyFunc必须返回和生成时完全相同的密钥字节切片 - 校验通过后,把用户 ID 或 username 存到
c.Data["user_id"]或c.Data["user"],后续 controller 直接用,不用重复解析 - 如果 token 过期或签名无效,
token.Valid是 false,但err可能为 nil —— 所以不能只看 err,要同时判断token.Valid和claims != nil
为什么 ParseWithClaims 总返回 “token is invalid”
这个错误最常出现在三个地方:密钥不一致、时间偏差过大、结构体字段未导出。
- 生成和解析用的密钥必须字节级相同,比如生成用
[]byte("abc"),解析就不能用[]byte("ABC")或多一个空格 - 服务器时间不准会导致
exp/iat校验失败,加个time.Sleep(1 * time.Second)测试下是否时间漂移 - 自定义 claims 结构体字段名首字母必须大写(如
UserID int),否则 JSON 序列化/反序列化失败,ParseWithClaims拿不到值 -
jwt.StandardClaims里的字段名是全大写(ExpiresAt,Issuer),别写成expiresat或exp—— 它内部靠反射匹配
刷新 token 时要注意什么
JWT 本身不可刷新,所谓“刷新”其实是用旧 token 解出用户信息,再签发一个新 token。这一步容易忽略权限延续性和时间重置逻辑。
- 旧 token 即使快过期了,只要
Valid == true就能解析出claims,别提前拒绝 - 新 token 的
ExpiresAt要重新计算,不能直接沿用旧的;否则刷新等于没刷 - 如果业务要求“刷新后旧 token 失效”,JWT 本身做不到,得配合 Redis 黑名单或版本号字段(如加个
TokenVersion字段存数据库) - 刷新接口本身也要走一遍
ParseToken校验,不能裸奔开放
真正麻烦的从来不是生成或解析 token,而是密钥管理、时间同步、错误分支覆盖,以及——当多个服务共用一套 JWT 验证逻辑时,确保所有地方用的 SigningMethod 和 key 字节完全一致。漏掉任何一个,都会在某个凌晨三点返回一个无法复现的 token is malformed。


















