令牌验证
发布: (2025年12月15日 GMT+8 00:42)
3 min read
原文: Dev.to
Source: Dev.to
概览
验证 JWT 的过程包括:
- 解析 token 字符串。
- 解码 header 和 payload。
- 使用相应的 secret/key 验证签名。
- 用 payload 数据填充自定义的
Claims结构体。 - 如果 token 有效则返回 claims,否则返回错误。
Claims 结构体
type Claims struct {
UserID string `json:"user_id"`
jwt.StandardClaims
}
Claims 结构体嵌入了 jwt.StandardClaims,并添加了自定义的 UserID 字段。
Secret Key
secretKey := GetJWTKey()
GetJWTKey()获取用于签名和验证 JWT 的全局 secret key。- 在本例中使用的算法是 HS256,因此密钥是
[]byte类型。 - 同一密钥用于所有用户。
解析 Token
token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return secretKey, nil
})
ParseWithClaims 的工作原理
- 拆分 token 为三部分:header、payload 和 signature。
- 解码 header 和 payload 到临时的
jwt.Token结构体。 - 调用密钥函数(上面的匿名函数)获取验证密钥(
secretKey)。 - 使用以下信息重新计算预期的签名:
- 已解码的 header 和 payload。
- secret key。
token.Method中指定的算法(例如 HS256)。
- 比较 重新计算的签名与 token 中的签名。
- 若两者匹配,则设置
token.Valid = true并用 payload 数据填充提供的Claims结构体。
内部 Token 表示
type Token struct {
Raw string // The original token string
Method jwt.SigningMethod // Signing algorithm (e.g., HS256)
Header map[string]interface{} // Header fields (e.g., "alg")
Claims jwt.Claims // Claims (populated with &Claims{})
Signature string // Base64‑encoded signature part
Valid bool // Result of signature & claim validation
}
使用解析后的 Claims
if claims, ok := token.Claims.(*Claims); ok && token.Valid {
return claims, nil
}
- 将通用的
token.Claims进行类型断言,得到具体的*Claims结构体。 - 若 token 有效,函数返回已填充的
claims;否则返回错误。
TL;DR 流程
jwt.ParseWithClaims接收tokenString。- 拆分 token → header、payload、signature。
- 将 header + payload 解码到临时的
jwt.Token。 - 调用密钥函数 → 返回
secretKey。 - 使用
secretKey和 header 中的算法重新计算签名。 - 将重新计算的签名与 token 的签名进行比较。
- 匹配 → token 有效,
token.Valid = true。 - 不匹配 → token 无效。
- 匹配 → token 有效,
- 用 payload 数据填充提供的
&Claims{}结构体。 - 将 claims(或错误)返回给调用方。