Go (Golang) 中的 JWT 令牌:完整指南
JSON Web Tokens (JWT) 是一种基于 JSON 的开放标准 (RFC 7519),用于创建访问令牌。JWT 广泛用于客户端和服务器之间的身份验证和信息交换。在 Go (Golang) 语言中,借助 golang-jwt/jwt 库,可以简单高效地处理 JWT 令牌。
在本文中,我们将详细讲解在 Go 中创建、签名、验证和使用 JWT 令牌。无论您是初学者还是经验丰富的开发者,只要希望在 Golang 项目中实现安全的身份验证,本文都将为您提供帮助。
安装 golang-jwt 库
要在 Go 中使用 JWT,需要安装 github.com/golang-jwt/jwt/v5 包。使用以下命令安装:
go get github.com/golang-jwt/jwt/v5安装后,即可在代码中导入该包:
import ( "github.com/golang-jwt/jwt/v5")JWT 令牌的结构
JWT 令牌由三部分组成,各部分之间用点号分隔:
- Header (头部) — 包含令牌类型 (JWT) 和签名算法 (例如 HS256 或 RS256)。
- Payload (载荷) — 包含数据 (claims),例如用户 ID、角色、过期时间等。
- Signature (签名) — 基于头部和载荷,使用密钥或 RSA/ECDSA 密钥对生成。
在 Go 中创建 JWT 令牌
下面是一个使用 HMAC-SHA256 (HS256) 算法创建 JWT 令牌的示例。这需要一个密钥。
package main
import ( "fmt" "time" "github.com/golang-jwt/jwt/v5")
func main() { // 密钥 (应安全存储) secretKey := []byte("my_secret_key_12345")
// 创建 claims (声明) claims := jwt.MapClaims{ "user_id": 123, "role": "admin", "exp": time.Now().Add(time.Hour * 24).Unix(), // 令牌有效期为 24 小时 "iat": time.Now().Unix(), }
// 创建令牌 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 使用密钥对令牌进行签名 tokenString, err := token.SignedString(secretKey) if err != nil { fmt.Println("创建令牌时出错:", err) return }
fmt.Println("生成的 JWT 令牌:") fmt.Println(tokenString)}验证和解析 JWT 令牌
使用相同的密钥来验证令牌的真实性。务必检查过期时间和签名。
package main
import ( "fmt" "github.com/golang-jwt/jwt/v5")
func main() { tokenString := "您的令牌在此" secretKey := []byte("my_secret_key_12345")
// 解析并验证令牌 token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { // 检查签名算法 if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("意外的签名方法: %v", token.Header["alg"]) } return secretKey, nil })
if err != nil { fmt.Println("验证令牌时出错:", err) return }
// 提取 claims if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { fmt.Println("令牌有效!") fmt.Printf("用户 ID: %v", claims["user_id"]) fmt.Printf("角色: %v", claims["role"]) } else { fmt.Println("令牌无效") }}使用结构化 claims
为了方便,您可以定义自己的 claims 结构体,实现 jwt.Claims 接口:
type CustomClaims struct { UserID int `json:"user_id"` Role string `json:"role"` jwt.RegisteredCl