必须用github.com/golang-jwt/jwt/v5,旧版存在CVE-2023-37582等签名绕过漏洞;解析时需显式传入类型指针、校验alg字段、限定ValidMethods,并让claims嵌入jwt.RegisteredClaims以校验exp/iat/iss等标准声明。

必须用 github.com/golang-jwt/jwt/v5,旧版 jwt-go 或 v4 存在 CVE-2023-37582 等签名绕过漏洞,已不可用。
Parse 时返回 token is invalid 但 token 格式完全正确
这几乎一定是算法未显式校验导致的静默失败。v5 默认拒绝 SigningMethodNone,而旧版需手动拦截;若 keyFunc 返回了错误或 nil,Parse 会直接报 token is invalid,不提示真实原因。
- 初始化解析时必须显式传入类型指针:
jwt.Parse[MyClaims](tokenStr, keyFunc),不能用泛型简化版(v5 已移除) -
keyFunc中务必检查token.Header["alg"]是否为预期值,例如只允许"HS256",拒绝"none"或"RS256"(除非你真配了 RSA) - 用
jwt.WithValidMethods([]string{"HS256"})显式限定签名方法,避免算法混淆
claims 结构体里没嵌 jwt.RegisteredClaims
仅验证签名只能防篡改,不防重放、不防过期、不防冒用。线上事故多源于解析后没校验标准声明字段。
- 必须让自定义 claims 嵌入
jwt.RegisteredClaims,它自带Validate()方法,可一键检查exp/iat/nbf/iss -
exp漏检 → 用户登出后 token 仍能访问接口 -
iat漏检 → 攻击者截获旧 token,在服务重启后继续使用(iat可设为服务启动时间戳) -
iss漏检 → 第三方伪造 issuer(如把iss: "my-api"改成iss: "attacker.com")
Gin 中间件里从非标准 header 提取 token
Authorization: Bearer <token> 是 RFC 6750 明确规定的传输方式,也是 Kong、Apigee、所有主流 WAF 和网关唯一默认识别的格式。
立即学习“go语言免费学习笔记(深入)”;
- 别用
X-Token、Token、query 参数或 cookie 传 bearer token —— 它们不是标准,也不被基础设施支持 - Gin 中间件应统一从
r.Header.Get("Authorization")提取,并按空格分割,校验前缀是否为"Bearer" - 密钥必须是
[]byte,且 HS256 要求长度 ≥32 字节;硬编码"secret"或短密钥等于主动开放爆破入口
最常被跳过的其实是 iat 和 iss 的联动校验:服务启动后签发的 token,其 iat 必须 ≥ 服务启动时间,否则旧 token 在进程重启后依然有效 —— 这个点在灰度发布和滚动更新时特别容易被忽略。


















