什麼是 JWT?JSON Web Token 完整指南
什麼是 JWT?
JSON Web Token(JWT)是一個開放標準(RFC 7519),定義了一種簡潔、自包含的方式,以 JSON 物件的形式在各方之間安全地傳輸資訊。JWT 是現代網頁應用程式中的主流權杖格式,廣泛用於使用者身份驗證、API 授權以及微服務之間的安全資料交換。
JWT 驗證如何運作
JWT 驗證遵循無狀態模式,無需伺服器端的會話儲存。了解這個流程是理解 JWT 為何成為現代 API 安全預設選擇的關鍵。
驗證流程
- 使用者登入 — 用戶端發送憑證(使用者名稱和密碼)到驗證伺服器。
- 伺服器建立 JWT — 伺服器驗證憑證,建立包含使用者身份和權限的 JWT,使用密鑰或私鑰進行簽名,然後返回給用戶端。
- 用戶端儲存權杖 — 用戶端儲存 JWT,通常存放在 localStorage、sessionStorage 或 HTTP-only cookie 中。
- 用戶端在每個請求中發送權杖 — 對於每個後續的 API 請求,用戶端使用 Bearer 方案在
Authorization標頭中包含 JWT:Authorization: Bearer <token>。 - 伺服器驗證權杖 — 伺服器驗證 JWT 簽名,檢查過期時間,並提取使用者聲明來授權該請求。
- 無需會話查詢 — 因為 JWT 包含所有必要的資訊,伺服器無需查詢資料庫或快取來識別使用者。
為什麼這很重要
傳統的基於會話的身份驗證將會話 ID 儲存在伺服器記憶體或資料庫中。每個經過驗證的請求都需要查詢。JWT 消除了這個查詢 — 權杖本身證明使用者的身份。這使得基於 JWT 的系統天生具有可擴展性,因為叢集中的任何伺服器都可以驗證權杖,而無需共享的會話狀態。
JWT 與基於會話的身份驗證對比
| 方面 | JWT 驗證 | 基於會話的驗證 | |------|----------|----------------| | 儲存 | 用戶端(在權杖中) | 伺服器端(在記憶體或資料庫中) | | 可擴展性 | 無需共享的會話儲存 | 需要跨執行個體的共享會話儲存 | | 跨網域 | 自然支援跨網域 | 難以共享會話 | | 行動裝置友善 | 是(無需 cookie) | 需要 cookie 支援 | | 撤銷 | 困難(直到權杖過期) | 簡單(從儲存中刪除會話) | | 有效載荷大小 | 每個請求較大(權杖在標頭中) | 最小(只有會話 ID) |
為什麼 JWT 被用於 API 安全
使 JWT 適合身份驗證的特性,同樣使其成為保護 API 的理想選擇。
無狀態且可擴展
每個 JWT 攜帶伺服器授權請求所需的全部資訊。無需查詢會話資料庫、無需檢查快取、無需跨伺服器同步狀態。負載均衡器可以將請求路由到任何伺服器執行個體,無需協調。
跨網域和跨來源
JWT 自然支援不同的網域和來源。由 auth.example.com 簽發的權杖可以用來存取 api.example.com 和 admin.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 架構中:
- 使用者登入身份提供者(IdP)— 例如 Auth0、Okta 或 Keycloak。
- IdP 簽發一個使用其私鑰簽名的 JWT。
- 使用者向多個應用程式出示此 JWT。
- 每個應用程式使用 IdP 的公鑰驗證簽名。
- 每個應用程式信任該權杖,無需在每次請求時與 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。貼上你的權杖,即可立即查看解碼後的標頭、有效載荷和簽名演算法。該工具幫助你了解權杖攜帶了哪些資料,並驗證其結構是否正確。