首頁 >web前端 >js教程 >掌握 JWT(JSON Web 令牌):深入探討

掌握 JWT(JSON Web 令牌):深入探討

DDD
DDD原創
2025-01-21 20:37:10736瀏覽

JSON Web Token (JWT):跨域身份驗證的熱門方案

本文介紹了當下最受歡迎的跨域身份驗證解決方案—JSON Web Token (JWT) 的原理和使用方法。

一、跨域身份驗證的挑戰

網路服務離不開使用者驗證。傳統流程如下:

  1. 使用者傳送使用者名稱和密碼給伺服器。
  2. 伺服器驗證成功後,將使用者角色、登入時間等相關資料儲存在目前會話中。
  3. 伺服器傳回一個 session_id 給用戶,寫入用戶的 Cookie。
  4. 使用者後續每次要求,都會透過 Cookie 將 session_id 傳送回伺服器。
  5. 伺服器收到 session_id 後,尋找預先儲存的數據,從而識別使用者身分。

此模型的擴展性差:單機環境沒問題,但伺服器叢集或跨網域面向服務的架構則需要會話資料共享,每台伺服器都能讀取會話。例如,網站 A 和網站 B 是同一家公司的關聯服務,要求使用者登入其中一個網站後,造訪另一個網站也能自動登入。一種解決方案是持久化會話數據,將其寫入資料庫或其他持久層,各服務收到請求後從持久層請求資料。此方案架構清晰,但工作量較大,且持久層故障會導致單點故障。另一種方案是伺服器完全不保存會話數據,所有數據保存在客戶端,每次請求都發送回伺服器。 JWT 正是這種方案的代表。

二、JWT 的原理

JWT 的原理是伺服器驗證後產生一個 JSON 物件並回傳給用戶,例如:

<code class="language-json">{"name": "Alice", "role": "admin", "expiration time": "2024年7月1日0:00"}</code>

之後使用者與伺服器通訊時需要回傳此 JSON 對象,伺服器完全根據此對象決定使用者身分。為防止使用者篡改數據,伺服器產生此物件時會添加簽名(細節後述)。伺服器不再保存任何會話數據,即伺服器變為無狀態的,更容易實現擴展。

三、JWT 的資料結構

實際的 JWT 類似:

Mastering JWT (JSON Web Tokens): A Deep Dive

它是一個很長的字串,由點 (.) 分隔成三個部分。注意 JWT 內部沒有換行符,此處分行只是為了方便顯示。 JWT 的三個部分如下:

  • Header (頭部)
  • Payload (酬載)
  • Signature (簽名)

一行表示為:Header.Payload.Signature

Mastering JWT (JSON Web Tokens): A Deep Dive

以下分別介紹這三個部分。

3.1 Header (頭)

Header 部分是一個 JSON 對象,描述 JWT 的元數據,通常如下:

<code class="language-json">{"alg": "HS256", "typ": "JWT"}</code>

其中 alg 屬性表示簽章演算法,預設為 HMAC SHA256 (HS256);typ 屬性表示此令牌的類型,JWT 令牌統一寫為 JWT。此 JSON 物件最終使用 Base64URL 演算法轉換為字串(細節後述)。

3.2 Payload (酬載)

Payload 部分也是一個 JSON 對象,用於儲存實際需要傳輸的資料。 JWT 定義了 7 個官方欄位可選:

  • iss (issuer):發行者
  • exp (expiration time):過期時間
  • sub (subject):主題
  • aud (audience):受眾
  • nbf (Not Before):生效時間
  • iat (Issued At):簽發時間
  • jti (JWT ID):序號

除了官方字段,還可以自訂私有字段。例如:

<code class="language-json">{"name": "Alice", "role": "admin", "expiration time": "2024年7月1日0:00"}</code>

注意,JWT 預設不會加密,任何人都可以讀取,因此不要在此部分放置秘密訊息。此 JSON 物件也需要使用 Base64URL 演算法轉換為字串。

3.3 Signature (簽名)

Signature 部分是前兩部分的簽名,用於防止資料竄改。首先需要指定一個金鑰 (secret),此金鑰只有伺服器知道,不能外洩給使用者。然後使用 Header 中指定的簽章演算法(預設為 HMAC SHA256)根據以下公式產生簽章:

<code class="language-json">{"alg": "HS256", "typ": "JWT"}</code>

計算出簽章後,將 Header、Payload 和 Signature 三部分組合成一個字串,各部分之間以 "點" (.) 分隔,即可傳回給使用者。

3.4 Base64URL

如前所述,Header 和 Payload 的序列化演算法是 Base64URL。此演算法基本上與 Base64 演算法類似,但有一些細微差別。作為令牌,JWT 有時可能放在URL 中(例如api.example.com/?token=xxx),Base64 中的三個字元、/ 和= 在URL 中有特殊含義,需要替換:= 被省略, 被替換為-,/ 被替換為_。這就是 Base64URL 演算法。

四、JWT 的使用方法

客戶端收到伺服器傳回的 JWT 後,可以儲存在 Cookie 或 localStorage 中。之後客戶端每次與伺服器通訊都需要攜帶此 JWT。可以將其放在 Cookie 中自動發送,但這無法跨域。更好的方法是將其放在 HTTP 請求頭的 Authorization 欄位中:

Authorization: Bearer

另一種方法是在跨域時將 JWT 放在 POST 請求的資料體中。

五、JWT 的幾個特性

(1) JWT 預設不加密,但可以加密。產生原始 Token 後,可以用金鑰再次加密。

(2) JWT 未加密的情況下,無法寫入秘密資料。

(3) JWT 不僅可以用於身份驗證,還可以用於資訊交換。有效使用 JWT 可以減少伺服器查詢資料庫的次數。

(4) JWT 最大的缺點是伺服器不保存會話狀態,無法在使用過程中撤銷某個令牌或更改令牌的權限。也就是說,JWT 一旦發出,就一直有效直到過期,除非伺服器部署額外邏輯。

(5) JWT 本身包含身份驗證訊息,一旦洩露,任何人都可以獲得令牌的所有權限。為減少被盜,JWT 的有效期限應設定得相對較短。對於一些較重要的權限,使用者在使用時應再次進行身份驗證。

(6) 為減少被盜,JWT 不應使用 HTTP 協定明文傳輸,而應使用 HTTPS 協定傳輸。

Leapcell:最佳無伺服器 Web 代管平台

Mastering JWT (JSON Web Tokens): A Deep Dive

最後,推薦一個部署 Web 服務的最佳平台:Leapcell

1. 多語言支援

  • 使用 JavaScript、Python、Go 或 Rust 開發。

2. 免費部署無限專案

  • 只按使用付費-無請求,無收費。

3. 無與倫比的成本效益

  • 隨選付費,無空閒費用。
  • 例如:25 美元支援 694 萬次要求,平均回應時間為 60 毫秒。

4. 簡化的開發者體驗

  • 直覺的 UI,輕鬆設定。
  • 全自動 CI/CD 管道和 GitOps 整合。
  • 即時指標和日誌記錄,提供可操作的見解。

5. 輕鬆擴充與高效能

  • 自動擴展,輕鬆處理高並發。
  • 零營運開銷-只需專注於建置。

Mastering JWT (JSON Web Tokens): A Deep Dive

在文件中了解更多!

Leapcell Twitter:https://www.php.cn/link/7884effb9452a6d7a7a79499ef854afd

以上是掌握 JWT(JSON Web 令牌):深入探討的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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