如何安全地解碼 JWT 並檢查其宣告
快速解答
JWT 是三個由點連接的 Base64URL 字串:header.payload.signature。使用 Base64URL 解碼對標頭和有效負載進行解碼以檢查聲明,但解碼僅讀取數據,不會驗證真實性。在信任任何聲明之前,請務必驗證伺服器上的簽名。使用我們的 JWT 解碼器檢查瀏覽器中的令牌。
介紹
JSON Web 令牌(JWT,RFC 7519)是一種緊密的、URL 安全性的令牌格式,用於驗證和授權。它有三個由點分隔的 Base64URL 編碼部分:header.payload.signature。標頭描述演算法,有效負載攜帶聲明(使用者 ID、角色、到期日),簽名證明令牌是由受信任方頒發的。至關重要的是,標頭和有效負載是經過編碼的,而不是加密的——任何人都可以讀取它們。
步步
-
將令牌分為三部分
JWT 看起來像 xxxxx.yyyyy.zzzzz。按點字元拆分以獲得標頭(第 0 部分)、有效負載(第 1 部分)和簽名(第 2 部分)。如果不完全是三個部分,則令牌格式錯誤。
-
Base64URL-解碼標頭
標頭是 Base64URL 編碼的 JSON 對象,例如 {"alg":"HS256","typ":"JWT"}。 Base64URL 使用 - 和 _ 代替 + 和 / 並省略填充。對其進行解碼,然後 JSON.parse 讀取演算法和類型。我們的 JWT 解碼器會自動執行此操作。
-
Base64URL 對有效負載進行解碼(聲明)
有效負載是宣告的 JSON 物件。註冊的聲明包括 iss(發行者)、sub(主題)、aud(受眾)、exp(到期)、nbf(不早於)、iat(發行時間)和 jti(代幣 ID)。私人聲明是特定於應用程式的(例如角色、電子郵件)。解碼和檢查,但在驗證之前不要信任。
-
檢查過期和未提前索賠
exp 和 nbf 是 Unix 時間戳記(秒)。如果當前時間超過 exp,則令牌已過期且必須被拒絕。如果目前時間早於nbf,則令牌尚未生效。檢查這些客戶端的使用者體驗,但在伺服器端強制執行它們以確保安全。
-
驗證伺服器上的簽章(絕不是客戶端)
HS256 的簽章為 HMAC-SHA256(secret, header.payload),RS256/ES256 的簽章為 RSA/ECDSA 簽章。驗證需要秘密或公鑰,該金鑰絕不能到達瀏覽器。使用 jsonwebtoken (Node) 或 jose 等函式庫進行驗證-切勿編寫自己的加密貨幣。
範例
典型的JWT(三個部分)
輸入: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpmeJf36POk6yJV_adQssw5c
輸出: Header: {"alg":"HS256","typ":"JWT"} Payload: {"sub":"1234567890","name":"John Doe","iat":1516239022}
使用標準聲明解碼有效負載
輸入: 真實身份驗證令牌的有效負載
輸出: {"sub":"user-42","iss":"freeonlinetoolsgo.com","exp":1767229200,"iat":1767225600,"role":"admin"}
過期令牌偵測
輸入: 過期:1609459200 (2021-01-01) 檢查於 2026-08-28
輸出: Token is expired —current time (1767225600) > exp (1609459200). Reject and prompt re-login.
常見問題
- 將解碼視為驗證:任何人都可以使用任何聲明和虛假簽名製作 JWT 。解碼讀取有效負載,但無法證明任何內容。在信任聲明之前,請始終使用伺服器上的秘密/公鑰驗證簽名。
- 使用「none」演算法:JWT 規範允許 alg: none 用於不安全的令牌。如果您的驗證者接受 alg: none,則攻擊者可以偽造令牌。配置您的程式庫以拒絕任何預期演算法並將其列入白名單。
- 在 localStorage 中儲存 JWT:XSS 可以讀取 localStorage 並竊取令牌。優先選擇 httpOnly、Secure、SameSite=Strict cookie 作為會話令牌,或使用刷新令牌 cookie 的短期記憶體令牌。
- 不檢查 exp/aud/iss:被盜的令牌在過期之前一直有效。始終檢查每個請求的 exp(過期)、aud(目標受眾)和 iss(發行者),以防止跨服務重播令牌。
提示
- 使用短期存取令牌(15 分鐘)加上長期刷新令牌 — 這會限制存取令牌被盜的視窗。
- 當多個服務驗證令牌時,優先選擇 RS256(非對稱)而不是 HS256(對稱):每個服務都取得公鑰,並且只有頒發者擁有私鑰。
- 在開發過程中使用我們的 JWT 解碼器來檢查伺服器正在發出的內容 - 它顯示解碼後的標頭、有效負載和人類可讀的聲明摘要,而無需將令牌發送到任何地方。
- 切勿將敏感資料(密碼、PII)放入 JWT 有效負載中 - 它是 Base64 編碼的,未加密,任何攔截令牌的人都可以讀取每個聲明。