🎫
← 返回教學列表

什麼是 JWT?JSON Web Token 完整指南

· 標籤: what-is-jwt, jwt-authentication, jwt-guide, api-security, token-based-auth

什麼是 JWT?

JSON Web Token(JWT)是一個開放標準(RFC 7519),定義了一種簡潔、自包含的方式,以 JSON 物件的形式在各方之間安全地傳輸資訊。JWT 是現代網頁應用程式中的主流權杖格式,廣泛用於使用者身份驗證、API 授權以及微服務之間的安全資料交換。

JWT 驗證如何運作

JWT 驗證遵循無狀態模式,無需伺服器端的會話儲存。了解這個流程是理解 JWT 為何成為現代 API 安全預設選擇的關鍵。

驗證流程

  1. 使用者登入 — 用戶端發送憑證(使用者名稱和密碼)到驗證伺服器。
  2. 伺服器建立 JWT — 伺服器驗證憑證,建立包含使用者身份和權限的 JWT,使用密鑰或私鑰進行簽名,然後返回給用戶端。
  3. 用戶端儲存權杖 — 用戶端儲存 JWT,通常存放在 localStorage、sessionStorage 或 HTTP-only cookie 中。
  4. 用戶端在每個請求中發送權杖 — 對於每個後續的 API 請求,用戶端使用 Bearer 方案在 Authorization 標頭中包含 JWT:Authorization: Bearer <token>
  5. 伺服器驗證權杖 — 伺服器驗證 JWT 簽名,檢查過期時間,並提取使用者聲明來授權該請求。
  6. 無需會話查詢 — 因為 JWT 包含所有必要的資訊,伺服器無需查詢資料庫或快取來識別使用者。

為什麼這很重要

傳統的基於會話的身份驗證將會話 ID 儲存在伺服器記憶體或資料庫中。每個經過驗證的請求都需要查詢。JWT 消除了這個查詢 — 權杖本身證明使用者的身份。這使得基於 JWT 的系統天生具有可擴展性,因為叢集中的任何伺服器都可以驗證權杖,而無需共享的會話狀態。

JWT 與基於會話的身份驗證對比

| 方面 | JWT 驗證 | 基於會話的驗證 | |------|----------|----------------| | 儲存 | 用戶端(在權杖中) | 伺服器端(在記憶體或資料庫中) | | 可擴展性 | 無需共享的會話儲存 | 需要跨執行個體的共享會話儲存 | | 跨網域 | 自然支援跨網域 | 難以共享會話 | | 行動裝置友善 | 是(無需 cookie) | 需要 cookie 支援 | | 撤銷 | 困難(直到權杖過期) | 簡單(從儲存中刪除會話) | | 有效載荷大小 | 每個請求較大(權杖在標頭中) | 最小(只有會話 ID) |

為什麼 JWT 被用於 API 安全

使 JWT 適合身份驗證的特性,同樣使其成為保護 API 的理想選擇。

無狀態且可擴展

每個 JWT 攜帶伺服器授權請求所需的全部資訊。無需查詢會話資料庫、無需檢查快取、無需跨伺服器同步狀態。負載均衡器可以將請求路由到任何伺服器執行個體,無需協調。

跨網域和跨來源

JWT 自然支援不同的網域和來源。由 auth.example.com 簽發的權杖可以用來存取 api.example.comadmin.example.com。這使得 JWT 成為單一登入(SSO)系統的基礎。

細粒度的授權

JWT 有效載荷可以包含角色、權限和組織成員資格的自訂聲明:

{
  "sub": "user_abc123",
  "role": "admin",
  "permissions": ["read:users", "write:users", "delete:users"],
  "org_id": "org_xyz789",
  "iat": 1516239022,
  "exp": 1516325422
}

API 伺服器直接從權杖中讀取這些聲明,無需任何額外的查詢。

JWT 用於單一登入(SSO)

單一登入是 JWT 最常見的使用場景之一。在典型的 SSO 架構中:

  1. 使用者登入身份提供者(IdP)— 例如 Auth0、Okta 或 Keycloak。
  2. IdP 簽發一個使用其私鑰簽名的 JWT。
  3. 使用者向多個應用程式出示此 JWT。
  4. 每個應用程式使用 IdP 的公鑰驗證簽名。
  5. 每個應用程式信任該權杖,無需在每次請求時與 IdP 通訊。

此模式使得一次登入即可授權存取數十個服務 — 電子郵件、檔案儲存、專案管理、人力資源系統 — 而無需每個服務都實現自己的登入流程。

JWT 安全最佳實踐

雖然 JWT 為 API 安全提供了堅實的基礎,但正確的實現至關重要。

保持權杖短期有效

exp(過期時間)聲明設定為較短的持續時間 — 存取權杖為 15 分鐘到 1 小時。使用較長有效期的刷新權杖(數天或數週)來獲取新的存取權杖,無需使用者重新驗證。

始終使用 HTTPS

JWT 不會加密其有效載荷。任何攔截到權杖的人都可以解碼並讀取其內容。始終通過 HTTPS 傳輸 JWT 以防止攔截。

驗證所有內容

始終驗證簽名、檢查權杖是否未過期、確認 aud(受眾)與你的應用程式相符,並拒絕具有意外演算法的權杖。

安全儲存權杖

在用戶端,盡可能將 JWT 儲存在 HTTP-only cookie 中,或對於單頁應用程式儲存在記憶體中。避免將提供敏感資料存取的權杖儲存在 localStorage。

常見的 JWT 誤解

"JWT 是加密的。" — 不是。JWT 是簽名的,而非加密的。有效載荷是 base64url 編碼的,這是可逆的。JWE(JSON Web Encryption)提供加密功能,但它是一個獨立的規範,不在標準 JWT 涵蓋範圍內。

"JWT 防止 CSRF。" — 本身不會。JWT 放在 Authorization 標頭中有幫助,但如果權杖儲存在 cookie 中,仍然需要 CSRF 防護。

"JWT 只能用於身份驗證。" — JWT 用於身份驗證,但也用於授權資料交換、無狀態會話以及服務之間的安全資訊共享。

線上解碼與探索 JWT

使用 JWT 解碼器工具來檢查任何 JSON Web Token。貼上你的權杖,即可立即查看解碼後的標頭、有效載荷和簽名演算法。該工具幫助你了解權杖攜帶了哪些資料,並驗證其結構是否正確。

什麼是 JWT?JSON Web Token 完整指南 - CoolTool