只要你做過或除錯過登入系統,就會遇到 JWT —— 一個在用戶端與伺服器間傳遞、用來證明「你是誰」的精簡 token。這篇說明它如何運作,以及如何安全地解讀。
三個部分
JWT 是三段以點號連接的 Base64URL 字串:header.payload.signature。
- Header(標頭) —— 中繼資料,主要是簽章演算法,例如
{"alg":"HS256","typ":"JWT"}。 - Payload(內容) —— claims,一個關於使用者與 token 的 JSON 物件。
- Signature(簽章) —— 對 header 與 payload 的密碼學簽章,用密鑰(或私鑰)產生,用來偵測竄改。
你可以用 JWT 解碼器拆開並讀出前兩段。
常見 claims
Payload 裝的是 claims,部分是標準化的:
sub—— 主體(通常是使用者 ID)。iss—— 簽發者(誰建立了這個 token)。iat—— 簽發時間(Unix 時間戳)。exp—— 到期時間(Unix 時間戳)。過了就該拒絕這個 token。aud—— 預期的接收對象。
再加上你的應用自訂的 claims(角色、email 等)。
JWT 如何用於驗證
典型的無狀態流程:你登入,伺服器回傳一個已簽章的 JWT,你的用戶端在每次請求都帶著它(通常放在 Authorization: Bearer … 標頭)。伺服器驗證簽章並檢查 exp —— 有效的話,就信任其中的 claims,不必查資料庫。這種無狀態正是它的主要賣點。
是簽章,通常不是加密
多數 JWT 是簽章(JWS),不是加密。簽章證明完整性與真實性,但 payload 只是 Base64URL 編碼 —— 任何人都能讀。所以:
- 絕不把機密放進 payload(密碼、API 金鑰、隱私資料)。
- 加密是另一回事(JWE),而且少見得多。
真正重要的安全規則
- 一律在伺服器端用你的密鑰/公鑰驗證簽章。 解碼(像本工具做的)不等於驗證。
- 檢查
exp。 過期的 token 必須拒絕。 - HS256 vs RS256: HS256 用一組共享密鑰;RS256 用私鑰簽、公鑰驗 —— 當多個服務需要驗證但不簽發時更合適。
- 絕不把真正的密鑰貼進線上工具。 解碼 token 檢視 claims 沒問題;驗證需要密鑰,應該放在你自己的程式裡。
解讀一個 token
要除錯驗證問題 —— token 過期了嗎?角色對嗎? —— 就解碼它、檢視 payload。免費的 JWT 解碼器會顯示 header 與 payload,並把 exp 換成可讀時間,全程在你的瀏覽器本機進行,token 不會上傳。