
本文介绍使用 Go 语言(基于 github.com/dgrijalva/jwt-go 库)安全、可靠地解析并提取 JWT Token 的 payload(即声明 Claims),包含完整示例代码、签名验证逻辑及关键注意事项。
本文介绍使用 go 语言(基于 github.com/dgrijalva/jwt-go 库)安全、可靠地解析并提取 jwt token 的 payload(即声明 claims),包含完整示例代码、签名验证逻辑及关键注意事项。
JWT(JSON Web Token)由三部分组成:Header、Payload(即 Claims)和 Signature。其中 Payload 是我们关心的核心数据,以 JSON 格式编码并 Base64Url 安全编码。但直接解码 Header 或 Payload 并不安全——它无法验证 Token 是否被篡改或过期。因此,正确做法是使用标准 JWT 库进行完整解析与校验。
以下是一个生产就绪的 Go 示例,使用 github.com/dgrijalva/jwt-go(注意:该库已归档,推荐新项目迁移到 github.com/golang-jwt/jwt/v5,但本文兼容原库用法):
import (
"log"
"github.com/dgrijalva/jwt-go"
)
func extractClaims(tokenStr string, hmacSecretString string) (jwt.MapClaims, error) {
hmacSecret := []byte(hmacSecretString)
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
// 验证签名算法是否符合预期(防算法混淆攻击)
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, jwt.ErrInvalidType
}
return hmacSecret, nil
})
if err != nil {
return nil, err
}
if !token.Valid {
return nil, jwt.ErrSignatureInvalid // 或自定义错误如 "token is invalid or expired"
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return nil, jwt.ErrInvalidType
}
return claims, nil
}
✅ 调用示例:
func main() {
tokenStr := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"
secret := "your-secret-key" // 必须与签发时使用的密钥一致
claims, err := extractClaims(tokenStr, secret)
if err != nil {
log.Fatalf("Failed to parse token: %v", err)
}
// 安全访问字段(需类型断言或使用 claims.GetXXX 方法)
sub, ok := claims["sub"].(string)
if ok {
log.Printf("Subject: %s", sub) // 输出: Subject: 1234567890
}
name, ok := claims["name"].(string)
if ok {
log.Printf("Name: %s", name) // 输出: Name: John Doe
}
admin, ok := claims["admin"].(bool)
if ok {
log.Printf("Admin: %t", admin) // 输出: Admin: true
}
}
⚠️ 重要注意事项:
-
密钥必须严格保密:
hmacSecret不得硬编码在源码中,应通过环境变量或密钥管理服务注入; -
务必校验
token.Valid:仅解析不校验等同于信任未签名数据,存在严重安全风险; -
显式检查签名算法:防止
none算法或 RSA/ECDSA 混淆攻击(如将 HMAC Token 误用 RSA 公钥验证); -
处理类型断言失败:
claims["xxx"]返回interface{},需按实际类型(string/bool/float64/[]interface{})安全转换; -
时效性校验:
jwt.MapClaims自动支持exp/nbf/iat字段验证(只要Parse时传入正确密钥且 Token 未过期); -
迁移建议:
dgrijalva/jwt-go已停止维护,新项目请使用官方维护的github.com/golang-jwt/jwt/v5,API 更清晰、安全性更高。
通过以上方式,你不仅能安全提取 Claims,还能确保 Token 的完整性、真实性和时效性,满足生产环境对身份凭证的严格要求。










