[隨筆] 簡述 JWT 的原理與運作方式

--

JSON Web Token 是一種開放標準(RFC 7519),該標準定義了一種簡單穩定的方式來表示身份驗證和授權數據,而且也被廣泛地運用在各式後端服務之中,特別是分散式服務,因為這類型服務很難依賴 cookies(難以處理跨域請求) 或 session (不同伺服器如何同步狀態?),因此無狀態的 JWT 就成為了另一種解方。

JWT 本身是由三個部分組成:HeaderPayloadSignature ,這三者會各自用 . 分隔,如此一來就是一個完整的 JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header

宣告 token 類型和使用了哪種雜湊或加密演算法,有些 JWT 甚至有 kid

  • typ :token 種類,通常都是 JWT
  • alg :雜湊或加密演算法(HMACRSAECDS
  • kid :當伺服器端有多把密鑰用於簽名時會有這個欄位,伺服器端會根據該欄位使用適合的密鑰驗證簽名。

Payload

RFC 7519 定義了 Payload 中的一些公認欄位:

  • iss:發行者
  • iat:發行時間
  • exp:到期時間
  • sub:主題,用字串(case-sensitive) 或 URI 表示這個 JWT 所夾帶的唯一識別訊息,用於確定該 token 是與某一特定使用者相關。
  • aud:收件人
  • nbf:不接受早於該欄位的時間,如果當前時間早於這個欄位,則表示 JWT 還未生效。
  • jti:唯一識別符,用來區分 JWT

Public Claims:向官方申請公開聲明

Private Claims:使用者自定義的訊息,可以放一些非機敏的資料。(JWT本身只使用 Base64進行編碼,因此不該存放機敏資料在 JWT

Signature

由三個部分組成:經過 Base64 編碼後的 headerpayload ,再加上 256-bit-secret有了這三者之後會透過特定的雜湊或加密演算法計算,結果就是 Signature

驗證方式

授權伺服器確認 Client 之後會發放一組 JWT ,此後 Client 對於資源伺服器的溝通都必須攜帶這組 JWT ,資源伺服器以此來確認 Client 身分。當 JWTHeaderPayload 被竄改,資源伺服器在驗證時還會再對 Client 攜帶的 JWT 進行簽名,並將簽名比對,竄改之後的 HeaderPayload 必定無法產生相同簽名,由此便可知道 JWT 不合法。

--

--

TingIāu “Ting” Kí

隨處可見 Backend Engineer,主要使用 Kotlin 。頭貼是 Suica Penguin,最喜歡的樂團是 ヨルシカ。