Go (Golang) 中的 JWT 令牌:golang-jwt 库及使用示例

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

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

开始课程

Go (Golang) 中的 JWT 令牌:golang-jwt 库完全指南



JSON Web Token (JWT) 是一种基于 JSON 的开放标准 (RFC 7519),用于创建访问令牌。JWT 广泛应用于身份验证和各方之间的信息交换。在 Go (Golang) 中,最流行且积极维护的 JWT 库是 golang-jwt/jwt/v5。在本文中,我们将详细介绍如何安装、配置和使用该库来构建安全的 Web 应用程序。



安装 golang-jwt 库



首先,使用 go get 将库添加到您的项目中:



go get github.com/golang-jwt/jwt/v5


安装后,在代码中导入该包:



import (    "github.com/golang-jwt/jwt/v5")


JWT 的主要组成部分



JWT 由三个用点分隔的部分组成:Header(头部)、Payload(载荷)和 Signature(签名)。golang-jwt 库为处理每个部分提供了便捷的结构:



  • Header — 包含关于令牌类型和签名算法的元数据(例如 HS256、RS256)。
  • Payload — 包含声明(claims),例如用户 ID、过期时间、角色和其他数据。
  • Signature — 使用密钥或密钥对(私钥/公钥)创建。


创建 JWT 访问令牌 (Access Token)



让我们看一个使用 HS256 算法(对称加密)创建访问令牌的示例。首先,定义一个包含自定义声明的结构体:



type CustomClaims struct {    UserID   int    `json:"user_id"`    Username string `json:"username"`    jwt.RegisteredClaims}


现在,创建一个生成令牌的函数:



func GenerateAccessToken(userID int, username string, secretKey []byte) (string, error) {    claims := CustomClaims{        UserID:   userID,        Username: username,        RegisteredClaims: jwt.RegisteredClaims{            ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)),            IssuedAt:  jwt.NewNumericDate(time.Now()),            Subject:   "access",        },    }

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString(secretKey)}


这里我们将令牌的生存时间设置为 15 分钟,这是访问令牌的标准做法。使用 jwt.NewNumericDate() 可以正确格式化时间。



验证和解析令牌



要验证令牌的真实性,需要提取声明并检查签名:



func ValidateToken(tokenString string, secretKey []byte) (*CustomClaims, error) {    token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, 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 { return nil, err }

if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid { return claims, nil }

return nil, fmt.Errorf("无效的令牌")}


在回调函数中检查签名算法非常重要,以避免算法替换攻击。



创建和刷新刷新令牌 (Refresh Token)



为了提高安全性,通常使用一对令牌:短生命周期的访问令牌和长生命周期的刷新令牌。刷新令牌允许在不重新输入用户名/密码的情况下获取新的访问令牌。



func GenerateRefreshToken(userID int, secretKey []byte) (string, error) {                    

推荐