JSON Web Token (JWT):跨域身份驗證的熱門方案
本文介紹了當下最受歡迎的跨域身份驗證解決方案—JSON Web Token (JWT) 的原理和使用方法。
一、跨域身份驗證的挑戰
網路服務離不開使用者驗證。傳統流程如下:
此模型的擴展性差:單機環境沒問題,但伺服器叢集或跨網域面向服務的架構則需要會話資料共享,每台伺服器都能讀取會話。例如,網站 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 類似:
它是一個很長的字串,由點 (.) 分隔成三個部分。注意 JWT 內部沒有換行符,此處分行只是為了方便顯示。 JWT 的三個部分如下:
一行表示為:Header.Payload.Signature
以下分別介紹這三個部分。
Header 部分是一個 JSON 對象,描述 JWT 的元數據,通常如下:
<code class="language-json">{"alg": "HS256", "typ": "JWT"}</code>
其中 alg 屬性表示簽章演算法,預設為 HMAC SHA256 (HS256);typ 屬性表示此令牌的類型,JWT 令牌統一寫為 JWT。此 JSON 物件最終使用 Base64URL 演算法轉換為字串(細節後述)。
Payload 部分也是一個 JSON 對象,用於儲存實際需要傳輸的資料。 JWT 定義了 7 個官方欄位可選:
除了官方字段,還可以自訂私有字段。例如:
<code class="language-json">{"name": "Alice", "role": "admin", "expiration time": "2024年7月1日0:00"}</code>
注意,JWT 預設不會加密,任何人都可以讀取,因此不要在此部分放置秘密訊息。此 JSON 物件也需要使用 Base64URL 演算法轉換為字串。
Signature 部分是前兩部分的簽名,用於防止資料竄改。首先需要指定一個金鑰 (secret),此金鑰只有伺服器知道,不能外洩給使用者。然後使用 Header 中指定的簽章演算法(預設為 HMAC SHA256)根據以下公式產生簽章:
<code class="language-json">{"alg": "HS256", "typ": "JWT"}</code>
計算出簽章後,將 Header、Payload 和 Signature 三部分組合成一個字串,各部分之間以 "點" (.) 分隔,即可傳回給使用者。
如前所述,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 代管平台
最後,推薦一個部署 Web 服務的最佳平台:Leapcell
在文件中了解更多!
Leapcell Twitter:https://www.php.cn/link/7884effb9452a6d7a7a79499ef854afd
以上是掌握 JWT(JSON Web 令牌):深入探討的詳細內容。更多資訊請關注PHP中文網其他相關文章!