Go (Golang) 中的 JWT 令牌:创建与验证(附示例)

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

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                    

推荐