beego默认不支持jwt认证,必须手动集成jwt库并绕过beego.auth和默认session机制;因其基于session的鉴权与jwt无状态特性冲突,混用将丧失token续期、黑名单、自定义字段等核心能力。

Beego 默认不支持 JWT 认证,必须手动集成 github.com/dgrijalva/jwt-go(注意:该库已归档,生产环境建议迁移到 github.com/golang-jwt/jwt/v5),并绕过 beego.Auth 和默认 session 机制——否则 token 无法跨实例生效、无法主动失效、也无法携带自定义字段。
为什么不能直接用 beego.Auth 做 JWT 鉴权
beego.Auth 是基于 session 的跳转中间件,只检查 c.GetSession("uid") 是否存在,和 JWT 完全无关。强行混用会导致:
- 每次请求仍要查 session 存储(如 file 或 memory),失去 JWT 的无状态优势
- token 中的
exp、role等字段被忽略,权限逻辑退化为“有 session 就放行” - refresh_token 无法实现,因为
beego.Session不提供过期间隙续期能力
如何在 BaseConroller 中统一解析 Authorization Header
所有 API 请求都应从 Authorization: Bearer <token></token> 提取 token 并校验,推荐封装为 ParseJWT() 方法,放在 BaseController.Prepare() 中调用:
- 用
c.Ctx.Input.Header("Authorization")获取原始 header 字符串 - 用
strings.SplitN(authStr, " ", 2)拆分,确保第二段非空且前缀是"Bearer" - 调用
jwt.ParseWithClaims(tokenStr, &MyClaims{}, keyFunc),其中keyFunc必须返回与签发时一致的密钥(HS256 用[]byte,RS256 用*rsa.PublicKey) - 校验失败时直接
c.Abort("401"),不要继续执行后续逻辑
示例关键片段:
func (c *BaseController) ParseJWT() (*MyClaims, error) {
auth := c.Ctx.Input.Header("Authorization")
if auth == "" {
return nil, errors.New("missing Authorization header")
}
parts := strings.SplitN(auth, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
return nil, errors.New("invalid auth format")
}
token, err := jwt.ParseWithClaims(parts[1], &MyClaims{}, func(t *jwt.Token) (interface{}, error) {
return []byte(beego.AppConfig.String("jwtkey")), nil
})
if err != nil || !token.Valid {
return nil, errors.New("invalid or expired token")
}
return token.Claims.(*MyClaims), nil
}
如何安全地签发和刷新 token
登录成功后,不要只返回一个长期有效的 token。应同时下发 access_token(短时效,如 15 分钟)和 refresh_token(长时效,如 7 天,但需存 Redis 黑名单):
-
access_token载荷里至少含uid、exp、iat,避免存敏感字段(如密码哈希) -
refresh_token不进 JWT,而是生成随机字符串,存入 Redis:SETEX refresh:<uid> 604800 <random_string></random_string></uid> - 客户端用
refresh_token请求/api/refresh时,先校验 Redis 中是否存在且匹配,再签发新access_token - 用户登出时,删掉 Redis 中对应
refresh:<uid></uid>键,并将旧access_token的jti加入黑名单(Redis Set)
容易被忽略的兼容性与安全细节
很多团队卡在上线前最后一刻,问题往往出在这些地方:
-
github.com/dgrijalva/jwt-go在 v4 之后有严重安全漏洞(CVE-2020-26160),2026 年必须用v5版本,API 有 breaking change:ParseWithClaims第三个参数类型变为jwt.Keyfunc,不再是func(*Token) (interface{}, error) - Beego 的
c.Ctx.Input.SiteURL()在反向代理后可能返回http,但 JWT 中的iss(issuer)若写死为https://api.example.com,校验会失败——建议从配置读取或动态构造 - 前端 localStorage 存 token 有 XSS 风险,如需更高安全等级,应改用 httpOnly Cookie(但需处理 CSRF,Beego 默认不内置 CSRF 中间件)











