Beego 不内置 JWT 鉴权,须手动集成并严格控制验签逻辑:必须用 ParseWithClaims 显式指定算法与密钥,禁止 jwt.Parse;Token 从 Authorization Header 提取并校验 issuer/audience;微服务调用需显式透传;密钥轮换需自实现。

Beego框架本身不内置 JWT 鉴权能力,必须手动集成并严格控制验签逻辑。直接套用示例代码、忽略算法协商或密钥管理,上线后大概率出现 401/403 或横向越权。
Beego 中 JWT 验证必须重写 ParseWithClaims 而非直接调用 Parse
默认 jwt.Parse 会尝试用任意算法(如 HS256、none)解码,攻击者可篡改 Header 将 "alg": "none" 发起混淆攻击,导致验签跳过。Beego 的中间件里必须显式指定算法并绑定密钥:
- 永远用
jwt.ParseWithClaims(tokenString, claims, func(*jwt.Token) (interface{}, error) { return []byte(secretKey), nil }) - 禁止使用
jwt.Parse+ 回调函数中动态返回密钥(易触发密钥泄露或类型转换 panic) - 若需支持 RS256,密钥必须是
*rsa.PublicKey类型,且func(*jwt.Token) (interface{}, error)内部需判断token.Method.Alg()并返回对应公钥
Beego Controller 中提取和校验 Token 的典型位置是 Prepare 方法
不是在每个 Get/Post 里重复写,而是统一前置拦截。但要注意 Beego 的 Prepare 不自动 abort 请求,必须手动调用 this.Abort("401") 或 this.Data["json"] = map[string]string{"error": "unauthorized"} + this.ServeJSON():
- Token 应从
this.Ctx.Input.Header.Get("Authorization")提取,格式为"Bearer xxx",需strings.TrimPrefix去掉前缀 - 不要从
Cookie或Query读 Token —— 这违反 JWT 最佳实践,也增加 CSRF 风险 - 验签失败时,
claims.Valid()只检查过期时间,还需手动验证claims.Issuer、claims.Audience是否匹配服务预期值
微服务间调用时,Beego 无法自动透传 JWT,必须显式注入 X-Forwarded-User 或 Authorization
Beego 是 MVC 框架,不是网关;它不自动携带上游请求的 Header 到下游 HTTP 调用。如果 A 服务用 Beego 接收请求、再调用 B 服务,B 服务收不到原始 Token:
- 必须在 A 服务的 Controller 里,把解析后的
claims.User.Id或完整 Token 写入req.Header.Set("Authorization", "Bearer "+token) - 若下游是 gRPC,不能传 JWT 字符串,而应提取
sub和roles放入metadata.MD - 警惕 Beego 的
this.Ctx.Request是只读副本,修改 Header 不影响后续外发请求,必须在http.NewRequest构造阶段注入
Beego 做 JWT 鉴权最易被忽略的点是:它不处理密钥轮换。所有示例代码都用硬编码 const KEY = "xxx",但真实微服务要求双密钥平滑切换(旧密钥仍可验签,新密钥用于签发)。这需要自己实现密钥加载器 + 缓存 + func(*jwt.Token) (interface{}, error) 中按 kid 查找对应密钥,而不是无脑返回一个固定值。











