Featured image of post 網路安全中 JWT 令牌與有狀態會話的比較Featured image of post 網路安全中 JWT 令牌與有狀態會話的比較

網路安全中 JWT 令牌與有狀態會話的比較

關於撤銷屬性和本機安全性,批評無狀態 JWT 令牌與有狀態伺服器資料庫會話。

介紹

身份驗證是每個 Web 應用程式的支柱。出現了兩種主要模式:無狀態 JWT(JSON Web 令牌) 身份驗證和 基於狀態會話 身份驗證。兩者都解決相同的問題——在後續請求中驗證用戶是誰——但它們在儲存、撤銷和安全屬性方面有根本的不同。本文提供了詳細的比較,以幫助您選擇適合您的應用程式的方法。


智威湯遜結構

JWT 是一個獨立的令牌,由三個以點分隔的 base64url 編碼段組成:

header.payload.signature
// Header
{
  "alg": "HS256",
  "typ": "JWT"
}
// Payload
{
  "sub": "user123",
  "iat": 1712345678,
  "exp": 1712349278,
  "role": "admin"
}
// Signature (HMAC-SHA256 of header + payload)
細分內容
標題演算法(HS256RS256)與令牌類型
有效負載宣告 — sub(主題)、iat(發佈於)、exp(過期)、自訂資料
簽名驗證令牌未被竄改

由於有效負載僅採用 Base64 編碼(未加密),因此敏感資料絕不能放置在有效負載中,除非使用 JWE(JSON Web 加密)。


基於會話的身份驗證

在基於會話的身份驗證中,伺服器儲存會話資料(通常在記憶體、Redis 或資料庫中)。客戶端僅在 cookie 中保存會話 ID(隨機的不透明字串):


頭對頭比較

方面智威湯遜會議
儲存位置客戶端持有所有資料伺服器保存會話資料
伺服器狀態無狀態 — 無需資料庫查找有狀態 — 需要會話儲存查詢
可擴充性非常好 - 沒有共用會話儲存多實例需要集中式Redis/DB
撤銷困難 — 有效期限至 exp立即 — 從儲存中刪除會話
代幣大小更大(數百位元組)小(會話 ID ~32 位元組)
XSS 漏洞JS (localStorage) 可存取的令牌JS 無法存取 httpOnly cookie
CSRF 保護需要人工處理SameSite cookie + CSRF 令牌

JWT 的撤銷挑戰

JWT 最顯著的弱點是撤銷。一旦發出,JWT 將保持有效,直到其 exp 聲明為止。如果使用者登出、更改密碼或被禁止,則在沒有伺服器端狀態的情況下令牌無法失效,這違反了無狀態前提。

緩解策略

1.短期存取令牌+刷新令牌:

// Access token: 15 minutes
// Refresh token: 7 days (stored in database)

訪問令牌的 TTL 很短,因此如果洩露,損害是有限的。刷新令牌儲存在伺服器端,因此可以撤銷

2.令牌黑名單(拒絕名單):

// On logout, add jti (JWT ID) to Redis with TTL matching token expiry
await redis.set(`blacklist:${jti}`, 'true', 'EX', remainingTTL);

這會重新引入伺服器狀態,但僅針對已撤銷的令牌,而不是所有活動會話。

3.輪換令牌簽署金鑰:

更改簽名密鑰會使所有令牌失效——這是一種生硬但有效的緊急工具。


XSS 和 XSRF 注意事項

威脅JWT(本地儲存)會話(httpOnly cookie)
XSS令牌透過 document.cookielocalStorage 被盜JS 無法存取令牌(僅 http)
CSRF不容易受到攻擊(手動授權標頭)沒有 SameSite 或 CSRF 令牌就容易受到攻擊

儲存在 localStorage 中的 JWT 容易受到 XSS - 任何注入的腳本都可以讀取它們。 HttpOnly cookie 可防止這種情況,但需要 CSRF 保護,因為 cookie 是自動發送的。

JWT 的最佳實踐: 將存取權杖儲存在 httpOnly、Secure、SameSite=Strict cookie(不是 localStorage)中。伺服器從 Authorization 標頭(而不是 cookie)讀取它,以避免 CSRF。

// Set JWT in httpOnly cookie
res.cookie('token', jwt, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 15 * 60 * 1000
});

混合方法

許多生產系統結合了這兩種模式:

方法存取令牌刷新令牌
僅限智威湯遜內存中的 JWT帶有長 exp 的 JWT
會話式不透明會話 ID
混合短暫的 JWT(15 分鐘)資料庫中不透明的刷新令牌

混合模型為您提供 JWT 對於大多數請求的無狀態效率,同時透過刷新令牌保留撤銷功能


決策矩陣

您的首要任務推薦方法
最小的伺服器資料庫負載JWT(無狀態)
即時使用者登出/禁止基於會話的
微服務/API網關JWT(傳遞)
行動應用程式JWT(無 cookie 儲存)
伺服器渲染的 Web 應用程式會話(httpOnly cookie)
第三方API存取JWT(不記名令牌)

結論

沒有普遍的贏家。 JWT 在分散式系統、行動應用程式和 API 優先架構方面表現出色,在這些架構中,無狀態性非常有價值。會話驗證為撤銷、登出和伺服器端安全實施提供進階控制。混合模式——由可撤銷刷新令牌支援的短期 JWT——提供了一種務實的折衷方案,既發揮了兩種方法的優點,也減輕了它們的缺點。