JSON Web Token (JWT) 是什麼?
在 5 分鐘內清楚了解 JSON Web Token (JWT) 的基本知識。
JSON Web Token (JWT) 廣泛應用於現代網絡應用程式和開放標準例如 OpenID Connect,促進身份驗證和授權。雖然官方的 RFC 7519 是一個重要的參考,但對於初學者來說會很難理解。在這篇文章中,我們將重點介紹 JWT 的核心概念,並用簡單的語言和例子來呈現。
我們為什麼需要 JWT?
如今,使用 JSON 在兩方之間交換數據是非常常見的。考慮以下代表用戶的 JSON 對象:
sub
是 "subject" 的縮寫,是 OpenID Connect 中的 標準聲明,用於表示用戶標識(用戶 ID)。
我們如何能夠保證這個 JSON 對象的完整性?換句話說,我們如何確認數據在傳輸過程中沒有被篡改?一個常見的解決方案是使用數字簽名。例如,我們可以使用 公鑰加密:服務器用其私鑰簽署 JSON 對象,客戶端可以用服務器的公鑰驗證簽名。
簡而言之,JWT 提供了一種標準化的方法來表示 JSON 對象及其簽名。
JWT 的格式
由於有很多算法可用於創建數字簽名,因此需要指定用於 JWT 簽名的算法。這是通過構造 JSON 對象來完成的:
alg
是 "algorithm" 的縮寫,typ
是 "type" 的縮寫。
通常,typ
被設為大寫的 JWT
。在我們的例子中,alg
是 HS256
,代表 HMAC-SHA256(我們將很快解釋),表示我們使用這個算法來創建簽名。
現在,我們擁有所有構成 JWT 的成分:
- 標頭 JSON:算法和類型
- 載荷 JSON:實際數據
- 簽名:涵蓋標頭和載荷的簽名
然而,像空格和換行符這樣的字符不利於網絡傳輸。因此,標頭和載荷需要進行 Base64URL 編碼。典型的 JWT 如下所示:
.
是分隔符。
讓我們把所有東西放在一起創建一個 JWT:
標頭
JSON: {"alg":"HS256","typ":"JWT"}
Base64URL 編碼: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
載荷
JSON: {"sub":"foo","name":"John Doe"}
Base64URL 編碼: eyJzdWIiOiJmb28iLCJuYW1lIjoiSm9obiBEb2UifQ
簽名
在 HMAC-SHA256 中,簽名是用密鑰創建的:
例如,假設密鑰為 some-great-secret
,簽名將變成:XM-XSs2Lmp76IcTQ7tVdFcZzN4W_WcoKMNANp925Q9g
。
JWT
最終的 JWT 是:
這個有效的 JWT 可以被擁有密鑰的任何一方驗證。
選擇簽名算法
如前所述,有多種算法可以用來創建數字簽名。我們以 HS256
作為例子,但它可能不夠強大,因為密鑰必須在各方之間共享(例如客戶端和服務器)。
在現實世界中,客戶端可能包括像 React 應用程式這樣的公開應用,無法保證安全保存密鑰。因此,首選的方法是在簽署 JWT 時使用公鑰加密(即非對稱加密)。讓我們從最受歡迎的算法開始:RSA。
RSA
RSA 是一個非對稱算法,使用一對密鑰:公鑰和私鑰。公鑰用於驗證簽名,而私鑰用於簽名。
RSA 的標頭 JSON 如下所示:
RS256
代表 RSA-SHA256,意味著簽名是使用 RSA 算法和 SHA256 哈希函數創建的。你還可以使用RS384
和RS512
來創建帶有 SHA384 和 SHA512 哈希函數的簽名。
簽名是用私鑰創建的:
我們可以再次組裝這些部分來創建一個 JWT,最終的 JWT 如下所示:
現在,客戶端可以在不知道私鑰的 情況下驗證簽名。
ECDSA
雖然 RSA 被廣泛採用,但它受到較大簽名尺寸的影響,有時超過標頭和載荷的合併尺寸。橢圓曲線數字簽名算法(ECDSA)是另一種非對稱算法,可以創建更緊湊的簽名,而且效能更高。
要為 ECDSA 生成私鑰,我們需要選擇一個曲線。這超出了這篇文章的範疇,但你可以在這裡找到更多信息。
ECDSA 的標頭 JSON 如下所示:
ES256
代表 ECDSA-SHA256,這意味著簽名是用 ECDSA 算法和 SHA256 哈希函數創建的。你也可以使用ES384
和ES512
來創建帶有 SHA384 和 SHA512 哈希函數的簽名。
簽名是用私鑰創建的:
最終的 JWT 保持與 RSA 相同的結構,但具有顯著縮短的簽名:
驗證 JWT
驗證 JWT 非常簡單,是創建 JWT 的逆過程:
- 使用
.
分隔符將 JWT 拆分為三個部分(標頭、載荷和簽名)。 - 使用 Base64URL 解碼標頭和載荷。
- 使用標頭中指定的算法和公鑰(對於非對稱算法)驗證簽名。
有許多可用的庫可以幫助進行 JWT 驗證,例如適用於 Node.js 和網頁瀏覽器的 jose。
總結
在這篇文章中,我們簡要地解釋了 JWT 的核心概念,以及如何創建和驗證它的概覽 。許多細節尚未被探索,我們會在未來的文章中覆蓋它們。
Logto 利用像 JWT 和 OpenID Connect 的開放標準來通過簡化的工作流程保護你的應用程式和 API。若你感興趣,可以免費試用(不需要信用卡)。