guest@blog.cmj.tw: ~/posts $

JSON Web Token (JWT)


I do NOT like, but I still have to use

JSONWebToken (JWT) 是一個 RFC-7519 的標準:透過 JSON 為基礎的溝通方式, 內容透過簽章 (JSON Web Signature, JWS) 或者是加密 (JSON Web Encryption, JWE), 用來保證雙方可以交換資訊可以做數位簽章或者是資料完整性的保護。

設計上 JWT 跟原本的 Session 差別在於:Session 需要在 Server 端儲存且具有狀態性, 而 Token 為基礎的 JWT 則把資訊儲存在 Token 本身來做到無狀態 (Stateless) 的特性。

格式 (Format)

JWT 的格式分為三個部分:Header、Payload 與 Signature,三者透過點 (.) 做連結。Header 用來標示 JWT 使用哪種加密演算法, 透過 JSON 的格式描述,其中包含了 alg 與 typ 兩個 key 值分別描述使用哪種簽名演算法與內容格式,最後透過 Base64URL 編碼。

在 Payload 本身則存放了各式各樣的內容,在 RFC 中提到需提供七個必須的內容:iss (Issuer)、sub (Subject)、aud (Audience)、 exp (Expiration)、nbf (Not Before)、iat (Issued At) 與 jti (JWT ID),七個內容都有其目的與必要性。

最後的 Signature 部分則是將 Header 與 Payload 透過 Header 提及的演算法做數位簽章。

問題

針對 JWT 本身因為內容明文除存在 Token 上 (不了解編碼與加密可以參考 PTT 這篇文章 ),內容本身沒辦法存放敏感資料。 假若內容需要再額外加密則就是使用 JWE 的方式傳遞內容。而敏感資訊存放在 Token 上、則又需要承擔資料洩漏的風險: 存在一種風險在於加密的密鑰洩漏但攻擊者又無法直接存取資料庫、或者使用的加密演算法出現新型態的安全性問題等。

跟 Session 比較起來,JWT 使用上的優勢在於減少資料庫的存取數量與次數。經過授權之後賦予的 JWT 伺服器無條件相信授權結果, 在一段時間內不會再次驗證授權狀況,這代表 revoke JWT 這個操作無法立即生效。如果要支援立即性的 revoke JWT 功能, 就需要針對資料層做存取來判斷 JWT 是否被註銷:無論透過白名單檢查 JWT 的合法性、還是黑名單的 revoked JWD。這表示 JWT 還是需要一定程度的資料存取。