Skip to content
Anonymous

深入淺出 JWT:現代 Web 驗證的原理、實踐與安全進階

JSON Web Token (JWT) 已成為現代 Web 應用程式驗證的主流標準。本文將從結構原理出發,深度解析安全性考量,並比較 Session、PASETO 等機制。同時,我們將探討 Token 撤銷策略與前端存儲的安全性權衡,幫助開發者建構更穩健的認證系統。

#JWT #Authentication #Security #Web Development #Backend

在現代的 Web 應用程式開發中,身份驗證 (Authentication)授權 (Authorization) 是最基礎也最重要的環節。隨著微服務 (Microservices) 與單頁應用 (SPA) 的興起,傳統的 Session-based 驗證機制逐漸顯得力不從心,而 JSON Web Token (JWT) 則因其「無狀態 (Stateless)」與「輕量化」的特性,成為了目前最主流的解決方案。

本文將深入探討 JWT 的運作原理,並將其與其他常見的驗證機制進行比較,同時涵蓋進階的安全實作建議,協助開發者建構更安全、可擴展的系統。


1. 什麼是 JWT?為什麼需要它?

JWT (JSON Web Token) 是一種開放標準 (RFC 7519),它定義了一種緊湊且自包含 (Self-contained) 的內容格式,用於在各方之間以 JSON 物件安全地傳輸資訊。這些資訊可以被驗證和信任,因為它們經過了數位簽章。

傳統 Session vs. JWT

在了解 JWT 之前,我們先回顧一下傳統的 Session-based Authentication

  1. 使用者登入:瀏覽器傳送帳密給伺服器。
  2. 伺服器建立 Session:驗證成功後,伺服器在記憶體或資料庫中建立一個 Session ID,並記錄使用者資訊。
  3. 回傳 Cookie:伺服器將 Session ID 透過 Set-Cookie 回傳給瀏覽器。
  4. 後續請求:瀏覽器每次請求都會自動帶上 Cookie,伺服器拿著 Cookie 中的 Session ID 去資料庫查找使用者。

痛點

  • 伺服器負擔:伺服器需要儲存所有在線使用者的 Session 資料(Stateful)。
  • 擴展性差 (Scalability):在多伺服器負載平衡 (Load Balancing) 架構下,Session 同步是一個難題(通常需要 Redis 等快取伺服器支援)。
  • CORS 問題:Cookie 在跨網域 (Cross-Domain) 場景下,搭配同源策略 (Same-origin policy) 處理較為複雜。

JWT 的優勢

  • 無狀態 (Stateless):Token 本身包含了所有必要的資訊(如 User ID、過期時間),伺服器無需查詢資料庫即可驗證使用者身份。
  • 跨網域友善:JWT 通常透過 HTTP Header (Authorization: Bearer <token>) 傳輸,不受 Cookie 的同源限制。
  • 適合微服務:一個微服務簽發的 Token,可以被其他信任該簽章的任務或服務直接驗證。

流程比較圖解

Session-based Flow

sequenceDiagram
    participant User
    participant Server
    participant DB
    User->>Server: 登入 (帳號/密碼)
    Server->>DB: 驗證帳密
    DB-->>Server: 驗證通過
    Server->>Server: 建立 Session ID (存入記憶體)
    Server-->>User: 回傳 Set-Cookie: SessionID
    Note over User, Server: 後續請求
    User->>Server: GET /api/data (帶 Cookie)
    Server->>Server: 讀取 Session ID
    Server->>DB: 查詢 Session 是否有效
    DB-->>Server: 有效 (User A)
    Server-->>User: 回傳資料

JWT Flow

sequenceDiagram
    participant User
    participant Server
    User->>Server: 登入 (帳號/密碼)
    Server->>Server: 驗證帳密 & 簽發 JWT
    Server-->>User: 回傳 Access Token
    Note over User, Server: 後續請求
    User->>Server: GET /api/data (Header: Bearer Token)
    Server->>Server: **驗證簽章 & 解碼 (無需查 DB)**
    Server-->>User: 回傳資料

2. JWT 的結構原理

一個 JWT 字串由三個部分組成,中間用 . 分隔:Header.Payload.Signature

A. Header (標頭)

通常包含兩部分資訊:Token 的類型 (typ) 和使用的簽章演算法 (alg)。

{
  "alg": "HS256",
  "typ": "JWT"
}

這段 JSON 會經由 Base64Url 編碼後形成第一部分。

B. Payload (內容)

這是存放實際資訊 (Claims) 的地方。Claims 分為三種:

  1. Registered Claims (註冊聲明):標準定義的欄位,如 iss (簽發者)、exp (過期時間)、sub (主題)、iat (簽發時間)。
  2. Public Claims (公開聲明):建議遵循 IANA JSON Web Token Registry 以免衝突。
  3. Private Claims (私有聲明):雙方約定好的自定義欄位,如 role: admin

⚠️ 重要提醒:Payload 僅僅是經過 Base64 編碼,並未加密!敏感資料(如密碼)絕對不可放入。

C. Signature (簽章)

這是最關鍵的安全防線。公式如下:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret
)

伺服器持有的 Secret Key 保證了資料的完整性。若 Payload 被竄改,簽章校驗將會失敗。


3. 進階安全實作:撤銷 (Revocation) 與 滾動機制

由於 JWT 是無狀態的,一旦簽發後除非過期,否則伺服器很難主動將其作廢。以下是幾種常見的進階方案:

Token Revocation(黑名單 vs 白名單)

  1. 黑名單 (Blacklist):當使用者登出時,將該 Token 存入 Redis 並設定過期時間。伺服器驗證 JWT 後,需額外檢查其是否存在於黑名單。
    • 優點:維持了大部分的效能,只需紀錄異常或提早失效的 Token。
    • 缺點:伺服器變回「部分有狀態 (Stateful)」。
  2. 白名單 (Whitelist):伺服器只允許存在於資料庫中的 Token 通過。
    • 優點:最高的控制力。
    • 缺點:每次請求都要查庫,失去了 JWT 原本的效能優勢。

Refresh Token Rotation(滾動式更新)

為了縮短 Access Token 的有效時間(例如 15 分鐘),我們引入較長效的 Refresh Token。

  • 運作流程:每次使用 Refresh Token 換取新的 Access Token 時,伺服器同時簽發一個「新的」Refresh Token 並作廢舊的。
  • 防禦重放攻擊 (Replay Attack):如果同一個 Refresh Token 被使用了兩次以上,代表可能發生 Token 竊取。伺服器應立即將該系列下的所有 Token 全數失效,強制使用者重新登入。

4. 前端 Token 存儲安全性研究

這是一個經典的爭議:到底存 localStorage 還是 Cookie

方式優點缺點 / 安全風險
localStorage實作極簡,支援跨域傳輸,容量較大。易受 XSS (跨站腳本) 攻擊:一段指令碼即可讀走所有 Token。
Cookie可設定 httpOnly 防禦 JavaScript 存取。易受 CSRF (跨站請求偽造) 攻擊:瀏覽器會自動帶上 Cookie。

最佳實踐方案: 建議存放在 httpOnly, Secure, SameSite=Strict 的 Cookie 中。為了防範 CSRF,後端應搭配 CSRF Token 或使用自定義 Header 驗證。


5. 現代替代方案:PASETO

PASETO (Platform-Agnostic Security Tokens) 被認為是 JWT 的繼承者。為什麼要考慮它?

  1. 防止演算法攻擊:JWT 允許在 Header 設定 alg: none,PASETO 則強制棄用有問題的加密模式。
  2. 安全性更強:它不提供太多靈活但危險的選擇,開發者較不容易因為設定錯誤而產生漏洞。
  3. 資料完整性:內建了更現代、更難破譯的簽章演算法(如 Ed25519)。

6. 結語

JWT 透過「以空間換取時間」的策略,完美契合了現代分散式系統的需求。然而,安全性不應僅僅依賴於標準本身,更在於開發者如何選擇存儲方式、設定過期時間以及實作 Token 滾動機制。

理解 JWT 的結構限制,並補齊撤銷與安全性權衡,你就能構建出既安全又高效的身份驗證系統。


🚀 實作演練:線上 JWT 解碼器

想親眼看看 JWT 內部結構長什麼樣子嗎?我特地開發了一個 JWT 解碼器工具,所有的解碼運算都在您的瀏覽器本地執行,保證隱私安全。

👉 立即試用 Personal HQ JWT Decoder


本文同步刊登於 Personal Digital HQ