首頁 >後端開發 >Golang >Golang 中的 JWT 令牌:安全 API 開發人員指南

Golang 中的 JWT 令牌:安全 API 開發人員指南

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-01-14 20:06:47309瀏覽

JWT Tokens in Golang: A Developer’s Guide to Secure APIs

引言

在現代Web開發中,安全且可擴展的認證至關重要。 JSON Web Tokens (JWT) 已成為實現這一目標的標準方法。在本篇部落格文章中,我們將探討JWT是什麼,它是如何運作的,以及如何在Golang中實現它。

什麼是JWT?

JSON Web Token (JWT) 是一種緊湊的、URL安全的表示聲明的方式,用於在雙方之間安全地傳輸聲明。它通常用於在API和分散式系統中對使用者進行身份驗證和授權。

JWT的結構

JWT由三個以點 (.) 分隔的部分組成:

<code>Header.Payload.Signature</code>

範例:

<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.reGQzG3OKdoIMWLDKOZ4TICJit3EW69cQE72E2CfzRE</code>

每個部分是:

  1. Header (頭部): 指定令牌類型 (JWT) 和簽章演算法 (HS256)。
<code>{
  "alg": "HS256",
  "typ": "JWT"
}</code>
  1. Payload (有效載荷): 包含聲明(使用者數據,例如ID、角色或名稱)。
<code>{
    "sub": "1234567890",
    "name": "John Doe",
    "admin": true,
    "iat": 1516239022
}</code>
  1. Signature (簽名): 使用加密簽章程序來確保令牌的完整性。讓我們詳細探討這一點。

簽署的建立方式:

  • 連接編碼的Header和Payload:
<code>  base64UrlEncode(header) + "." + base64UrlEncode(payload)</code>
  • 簽名結果:
    • 使用秘密金鑰或私鑰使用加密簽章演算法(例如,HMACSHA256、RS256)。
  • 附加簽名: 最終的JWT變成
<code>  header.payload.signature</code>

JWT的工作原理

  1. 客戶端將登入憑證傳送到伺服器。
  2. 如果有效,伺服器將產生JWT並將其傳回給客戶端。
  3. 客戶端儲存JWT(例如,在localStorage或cookie中)。
  4. 對於每個請求,客戶端都在Authorization標頭中包含JWT:Authorization: Bearer
  5. 伺服器在每次請求時驗證JWT。
    • 使用接收的Header和Payload重新計算簽章。
    • 將重新計算的簽章與接收的簽章進行比較。

在Golang中實作JWT

Golang開發人員可以利用優秀的golang-jwt/jwt函式庫來處理JWT。此庫提供了創建、簽署和驗證JWT的強大功能。您可以在此處找到它。

但是,管理JWT通常需要重複的任務,例如配置簽署方法、解析令牌和驗證聲明。為了簡化這一點,我編寫了一個自訂套件來包裝golang-jwt的功能。您可以在此處查看我的包。

以下是如何使用我的自訂JWT套件的範例。

<code class="language-go">package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/golang-jwt/jwt/v5"
    jwtutil "github.com/kittipat1413/go-common/util/jwt"
)

type MyCustomClaims struct {
    jwt.RegisteredClaims
    UserID string `json:"uid"`
}

func main() {
    ctx := context.Background()
    signingKey := []byte("super-secret-key")
    manager, err := jwtutil.NewJWTManager(jwtutil.HS256, signingKey)
    if err != nil {
        log.Fatalf("Failed to create JWTManager: %v", err)
    }

    // Prepare custom claims
    claims := &MyCustomClaims{
        RegisteredClaims: jwt.RegisteredClaims{
            ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)),
            Issuer:    "example-HS256",
            Subject:   "example-subject",
        },
        UserID: "abc123",
    }

    // Create the token
    tokenStringHS256, err := manager.CreateToken(ctx, claims)
    if err != nil {
        log.Fatalf("Failed to create token: %v", err)
    }
    fmt.Println("Generated Token:", tokenStringHS256)

    // Validate the token
    parsedClaims := &MyCustomClaims{}
    err = manager.ParseAndValidateToken(ctx, tokenStringHS256, parsedClaims)
    if err != nil {
        log.Fatalf("Failed to validate token: %v", err)
    }

    fmt.Printf("Token is valid! UserID: %s, Issuer: %s\n", parsedClaims.UserID, parsedClaims.Issuer)
}</code>

您可以在GitHub上瀏覽我的套件的完整實作和文件:此處。

JWT最佳實踐

  1. 使用HTTPS: 始終透過安全通道傳送令牌。
  2. 設定過期時間: 包含合理的exp以限制令牌濫用。
  3. 保護金鑰: 使用環境變數或金鑰管理員安全地儲存金鑰。
  4. 避免在有效載荷中使用敏感資料: 只包含非關鍵資訊。
  5. 使用刷新令牌: 將JWT與刷新令牌配對以安全地延長會話。

結論 ?

JWT是用於安全、無狀態身份驗證的強大工具。簽名確保了令牌的完整性和真實性,使JWT成為API和分散式系統的理想選擇。使用像jwt-go這樣的函式庫,您可以輕鬆地在Golang專案中實作JWT。

☕ 支持我的工作 ☕

如果您喜歡我的工作,請考慮請我喝杯咖啡!您的支持幫助我繼續創作有價值的內容並分享知識。 ☕

以上是Golang 中的 JWT 令牌:安全 API 開發人員指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn