必须显式嵌入jwt.registeredclaims,否则exp、iat等标准字段不会被自动校验;v5强制要求通过结构体嵌入而非map或字符串模拟,且密钥需≥32字节、验证时必须调用token.valid。

jwt.RegisteredClaims 必须显式嵌入自定义结构体,否则 exp、iat 等标准字段不会被自动校验 —— 这是多数人 token 总提示 “invalid or malformed” 的根本原因。
为什么 ParseWithClaims 总返回 “token is invalid”
不是密钥错,也不是算法不匹配,而是 claims 结构体没按 v5 规范定义。v5 版本强制要求标准时间字段(如 ExpiresAt)必须通过 jwt.RegisteredClaims 嵌入,不能靠 map[string]interface{} 或手动加 "exp" 字符串键模拟。
-
jwt.MapClaims仍可用,但仅适合极简场景;一旦需要Valid()自动校验过期、签发时间等,就必须用结构体嵌入方式 - 错误写法:
jwt.MapClaims{"user_id": 123, "exp": time.Now().Add(time.Hour).Unix()}→token.Valid永远为 false - 正确写法:定义
type Claims struct { UserID int `json:"user_id"` jwt.RegisteredClaims },然后传指针给ParseWithClaims - v5 默认启用
VerifyExpiresAt和VerifyIssuedAt,若结构体里没RegisteredClaims,这些检查直接失败
HS256 密钥长度不够会静默失败
Go JWT 库对 HMAC 密钥长度有隐式要求:SigningMethodHS256 实际依赖 SHA-256,而 RFC 2104 要求密钥长度 ≥ 哈希输出长度(32 字节)。低于该长度时,SignedString 不报错,但生成的 token 在其他语言(如 Node.js)或某些安全扫描工具中无法验证。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 硬编码
[]byte("my-secret")(9 字节)→ 可运行,但不符合规范,存在兼容性风险 - 生产环境应使用至少 32 字节密钥:可通过
openssl rand -hex 32生成,或用 Go 代码crypto/rand.Read(make([]byte, 32)) - 密钥必须从环境变量或 secret manager 加载,绝不可提交到代码库
- 若用 RSA,公钥/私钥 PEM 格式必须完整(含
-----BEGIN RSA PRIVATE KEY-----等头尾),且私钥不能加密(即无DEK-Info行)
中间件里解析 token 后必须调用 token.Valid
只调用 jwt.ParseWithClaims 并不等于完成验证 —— 它只做解析和签名比对,exp、nbf、iat 等时间校验需显式触发 token.Valid 或传入 jwt.WithValidator 函数。
- 常见错误:解析后直接取
claims.UserID,却忽略if !token.Valid { return }→ 过期 token 仍被放行 - 正确顺序:先
ParseWithClaims,再if err != nil || !token.Valid { ... } - 若需自定义校验(如检查
Issuer是否为"myapp"),应在KeyFunc返回密钥后,额外在解析后比对claims.Issuer - Gin 中间件示例里常漏掉这一步,导致“看似鉴权实则裸奔”
token 存储位置决定 XSS 和 CSRF 风险等级
JWT 本身无状态,但前端存储方式直接决定攻击面:存 localStorage 是最大误区,存 Cookie 则必须配对设置 HttpOnly + Secure + SameSite=Strict。
- localStorage/sessionStorage → 完全暴露于 XSS,攻击者可直接读取并重放 token
- Cookie 但未设
HttpOnly→ 同样可被 XSS 读取 - Cookie 设了
HttpOnly但没Secure→ HTTP 下明文传输,中间人可截获 - 推荐组合:
Set-Cookie: token=xxx; HttpOnly; Secure; SameSite=Strict; Path=/,配合短时效(如 15 分钟)+ refresh token 机制
Valid 到底要不要手动判、以及 cookie 属性漏一个就前功尽弃。这些点不抠清楚,配置再全也白搭。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










