golang,go,博客,开源,编程
jwt-go
是一个用于处理 JSON Web Tokens (JWT) 的 Go 语言库。JWT 是一种开放标准(RFC 7519),用于在各方之间以简洁、URL 安全的方式传递声明。JWT 常用于身份验证和信息交换,尤其在分布式系统中广泛使用。jwt-go
提供了创建、解析和验证 JWT 的功能,使得在 Go 中处理 JWT 变得简单和高效。
首先,通过 go get
安装 jwt-go
:
go get github.com/golang-jwt/jwt/v4
需要注意的是,jwt-go
已经被社区更新和维护,并且现在采用了版本控制,因此推荐使用 v4
版本。
JWT 通常由三个部分组成,格式如下:
Header.Payload.Signature
JWT
)和签名算法(如 HS256
或 RS256
)。JWT 的结构非常简单,由三部分组成,每部分通过 .
分隔开来:
header.payload.signature
Header:通常是一个 JSON 对象,描述签名使用的算法(如 HS256
或 RS256
)。例如:
{
"alg": "HS256",
"typ": "JWT"
}
Payload:包含 Claims,Claims 是有关实体(通常是用户)和其他数据的声明。常见的标准 Claims 包括:
iss
(Issuer):签发者。sub
(Subject):主题,通常是用户标识符。iat
(Issued At):签发时间。exp
(Expiration Time):过期时间。aud
(Audience):受众。示例 Payload:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Signature:为了生成签名部分,需要将 Header 和 Payload 编码为 Base64 字符串,然后用签名算法(如 HMAC SHA256 或 RSA)对其进行签名,密钥通常由服务端持有。
jwt-go
提供了非常方便的 API 来创建和签名 JWT。
以下是一个简单的示例,创建一个 HS256
算法的 JWT:
package main
import (
"fmt"
"log"
"time"
"github.com/golang-jwt/jwt/v4"
)
var secretKey = []byte("mySecretKey") // 用于签名和验证的密钥
func main() {
// 创建一个新的 token
token := jwt.New(jwt.SigningMethodHS256)
// 设置声明(Claims)
claims := token.Claims.(jwt.MapClaims)
claims["sub"] = "1234567890"
claims["name"] = "John Doe"
claims["iat"] = time.Now().Unix()
// 签名并产生完整的 token 字符串
tokenString, err := token.SignedString(secretKey)
if err != nil {
log.Fatalf("Error signing the token: %v", err)
}
fmt.Println("Generated Token:", tokenString)
}
jwt.New(jwt.SigningMethodHS256)
创建一个新的 JWT 对象,使用 HS256
签名算法。claims["sub"] = "1234567890"
设置了 JWT 的声明(payload)。token.SignedString(secretKey)
通过提供的密钥签名该 token,并返回最终的 JWT 字符串。jwt-go
支持多种签名算法,例如:
HS256
:HMAC SHA256RS256
:RSA SHA256例如,使用 RSA 签名算法时:
// 假设你已经有了 RSA 私钥
privateKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(rsaPrivateKey))
if err != nil {
log.Fatal("Failed to parse private key:", err)
}
token := jwt.New(jwt.SigningMethodRS256)
claims := token.Claims.(jwt.MapClaims)
claims["sub"] = "1234567890"
claims["name"] = "John Doe"
claims["iat"] = time.Now().Unix()
tokenString, err := token.SignedString(privateKey)
if err != nil {
log.Fatal("Failed to sign token:", err)
}
fmt.Println("Generated RSA Token:", tokenString)
在这种情况下,你需要先通过 RSA 私钥来签名 JWT,而不是使用 HS256
算法的对称密钥。
解析和验证 JWT 同样也非常简单。你可以使用 jwt-go
来验证 JWT 的签名是否有效,并获取其 payload。
下面是如何解析一个 JWT,并验证它的签名:
package main
import (
"fmt"
"log"
"github.com/golang-jwt/jwt/v4"
)
var secretKey = []byte("mySecretKey")
func main() {
tokenString := "your_jwt_token_string_here" // 从客户端获取的 JWT 字符串
// 解析并验证 JWT
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// 校验 token 使用的签名算法
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method %v", token.Header["alg"])
}
// 返回密钥用于验证签名
return secretKey, nil
})
if err != nil {
log.Fatal("Error parsing token:", err)
}
// 验证 token 是否有效
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
fmt.Println("Token is valid")
fmt.Println("Claims:", claims)
} else {
fmt.Println("Invalid token")
}
}
jwt.Parse(tokenString, keyFunc)
用来解析 JWT,并验证其签名。keyFunc
是一个函数,用来返回签名验证时所需的密钥。token.Claims.(jwt.MapClaims)
用于提取 JWT 中的声明部分(Payload)。token.Valid
用来检查 JWT 是否有效。通常情况下,JWT 会包含 exp
声明,表示过期时间。你可以通过解析后的 claims 来检查 token 是否过期:
if exp, ok := claims["exp"].(float64); ok {
if int64(exp) < time.Now().Unix() {
fmt.Println("Token has expired")
} else {
fmt.Println("Token is valid")
}
}
除了标准的声明(如 sub
, iat
, exp
等),你可以自定义声明,以满足业务需求。
type CustomClaims struct {
Username string `json:"username"`
jwt.RegisteredClaims
}
func main() {
// 创建一个新的 token
claims := &CustomClaims{
Username: "john_doe",
RegisteredClaims: jwt.RegisteredClaims{
Issuer: "myapp",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(secretKey)
if err != nil {
log.Fatal("Failed to sign token:", err)
}
fmt.Println("Generated Custom Token:", tokenString)
}
CustomClaims
包含了自定义的字段(如 Username
),同时嵌套了 jwt.RegisteredClaims
,以支持标准声明。jwt.NewWithClaims()
用于创建带有自定义声明的 JWT。jwt-go
库提供了一个简单且功能强大的 API 来处理 JWT。你可以用它来:
HS256
或 RS256
)。jwt-go
是构建现代 Web 应用、API、微服务和分布式系统时,进行认证和授权的一个非常重要的工具。