返回
JWT的原生实现,确保数据传输安全
后端
2023-11-27 04:43:10
JWT(JSON Web Token)是一种基于JSON的安全令牌,可以用于在不同系统之间传输认证信息。它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
- 头部:包含JWT的元数据,例如使用的算法和令牌的类型。
- 载荷:包含要传输的实际数据,例如用户ID或角色。
- 签名:使用头部和载荷计算出的哈希值,用于验证令牌的完整性。
JWT是一种非常流行的令牌,因为它是安全的、紧凑的,并且很容易实现。它被广泛用于各种应用中,例如API认证、单点登录和用户授权。
使用golang原生实现JWT非常简单。首先,我们需要导入必要的库:
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"time"
)
接下来,我们需要创建一个函数来生成JWT令牌:
func CreateJWT(claims map[string]interface{}) (string, error) {
header := map[string]interface{}{
"typ": "JWT",
"alg": "HS256",
}
payload := map[string]interface{}{
"iss": "my-app",
"iat": time.Now().Unix(),
"exp": time.Now().Add(time.Hour * 24).Unix(),
"claims": claims,
}
headerJSON, err := json.Marshal(header)
if err != nil {
return "", err
}
payloadJSON, err := json.Marshal(payload)
if err != nil {
return "", err
}
headerBase64 := base64.RawStdEncoding.EncodeToString(headerJSON)
payloadBase64 := base64.RawStdEncoding.EncodeToString(payloadJSON)
signature := hmac.New(sha256.New, []byte("my-secret"))
signature.Write([]byte(headerBase64 + "." + payloadBase64))
signatureBase64 := base64.RawStdEncoding.EncodeToString(signature.Sum(nil))
return headerBase64 + "." + payloadBase64 + "." + signatureBase64, nil
}
最后,我们需要创建一个函数来验证JWT令牌:
func VerifyJWT(token string) (map[string]interface{}, error) {
parts := strings.Split(token, ".")
if len(parts) != 3 {
return nil, errors.New("invalid JWT token")
}
headerJSON, err := base64.RawStdEncoding.DecodeString(parts[0])
if err != nil {
return nil, err
}
payloadJSON, err := base64.RawStdEncoding.DecodeString(parts[1])
if err != nil {
return nil, err
}
signature := hmac.New(sha256.New, []byte("my-secret"))
signature.Write([]byte(parts[0] + "." + parts[1]))
expectedSignature := base64.RawStdEncoding.EncodeToString(signature.Sum(nil))
if parts[2] != expectedSignature {
return nil, errors.New("invalid JWT signature")
}
payload := map[string]interface{}{}
err = json.Unmarshal(payloadJSON, &payload)
if err != nil {
return nil, err
}
return payload, nil
}
现在,我们可以使用这些函数来生成和验证JWT令牌。例如,我们可以创建一个包含用户ID和角色的JWT令牌:
claims := map[string]interface{}{
"user_id": 1,
"role": "admin",
}
token, err := CreateJWT(claims)
if err != nil {
// handle error
}
fmt.Println(token)
然后,我们可以使用VerifyJWT函数来验证令牌:
payload, err := VerifyJWT(token)
if err != nil {
// handle error
}
fmt.Println(payload)
如果令牌有效,那么VerifyJWT函数将返回包含用户ID和角色的payload。