Go JWT Token 字符串解密方法详解
Go语言的JWT库生成的Token字符串并非直接解密,而是通过验证其签名来确认其完整性和有效性。 解密指的是提取Token中的Payload部分,Payload中包含用户数据等信息。 以下步骤详细说明如何提取和验证:
Token分割: 将Token字符串按照点号 (.
) 分割成三个部分:头部 (Header)、负载 (Payload) 和签名 (Signature)。
Payload解码: 使用Base64解码Payload部分,得到一个JSON对象。
JSON解析: 将解码后的JSON对象解析成Go语言的map[string]interface{}
类型,方便访问其中的字段。
数据提取: 从解析后的map中获取需要的字段,例如用户ID ("uid")。
签名验证 (关键步骤): 这步至关重要,它确保Token未被篡改。 你需要使用与生成Token时相同的密钥来验证Signature部分。 验证失败则表示Token无效或被篡改。
以下是一个示例代码,演示如何提取Payload并进行签名验证 (需补充签名验证部分):
import (
"encoding/base64"
"encoding/json"
"fmt"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
)
// 自定义错误类型
var (
ErrMalformedToken = fmt.Errorf("malformed token")
ErrTokenExpired = fmt.Errorf("token expired")
ErrSignatureInvalid = fmt.Errorf("invalid signature")
)
// 提取和验证Token (签名验证部分需补充)
func VerifyAndDecodeToken(tokenString, signingKey string) (map[string]interface{}, error) {
parts := strings.Split(tokenString, ".")
if len(parts) != 3 {
return nil, ErrMalformedToken
}
payloadBytes, err := base64.StdEncoding.DecodeString(parts[1])
if err != nil {
return nil, ErrMalformedToken
}
claims := jwt.MapClaims{}
if err := json.Unmarshal(payloadBytes, &claims); err != nil {
return nil, ErrMalformedToken
}
// 签名验证 (此处需要补充你的签名验证逻辑,使用signingKey)
// token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
// return []byte(signingKey), nil
// })
// if err != nil {
// return nil, fmt.Errorf("token verification failed: %w", err)
// }
// if !token.Valid {
// return nil, ErrSignatureInvalid
// }
if claims["exp"] == nil || time.Now().Unix() > claims["exp"].(float64) {
return nil, ErrTokenExpired
}
return claims, nil
}
func main() {
// ... (你的代码,调用VerifyAndDecodeToken函数) ...
}
注意: 代码中的签名验证部分被注释掉了,你需要根据你的实际情况,使用jwt.ParseWithClaims
函数并提供正确的signingKey
来完成签名验证。 这部分代码需要根据你使用的JWT库和密钥管理方式进行调整。 切勿在代码中直接硬编码密钥。 使用环境变量或更安全的密钥管理方案。