JWT ( JSON Web Token ) 介紹

https://medium.com/企鵝也懂程式設計/jwt-json-web-token-原理介紹-74abfafad7ba

JWT 是由三個JSON object,並且用**.**來做區隔,而這三個部分會各自進行編碼,組成一個JWT字串:xxxxx.yyyyy.zzzzz

而這三個片段分別是:

  1. Header
  2. Payload
  3. Signature

我們可以透過 https://www.jwt.io/ 來產生JWT:

Header

{
  "alg": "HS256", // **Algorithm**
  "typ": "JWT" // **Type**
}

"alg"

這裡是定義簽名演算法的地方,HS256 全稱是 HMAC with SHA-256

告訴後端伺服器,這個 JWT 的第三部分(Signature)是用 SHA-256 雜湊演算法配合 Secret(對稱式密鑰) 計算出來的。

  • 驗證邏輯: 當後端收到 Token,會根據 alg: HS256寫的算法算一次。如果算出來的結果跟 Token 裡的簽名一模一樣,就代表資料沒被改過。
  • 漏洞原理: 因為後端會根據alg決定演算法執行,所以如果後端判斷不夠嚴謹,則把 Header 改成 {"alg": "none"}後端就會「不驗證簽名」直接放行。後端驗證邏輯必須「寫死」預期使用的演算法(例如只接受 HS256)。

"typ"

這代表 「權杖類型」

  • 這是一個固定值,宣告這個物件遵循 JSON Web Token 標準。
  • 它的意義: 幫助處理多種不同類型權杖的系統快速識別:「喔!這是一個 JWT,請用 JWT 的邏輯來解析我。」

PayLoad

建議依據JWT 規範(RFC 7519)中定義的預設欄位:

  • sub (Subject):使用者唯一識別碼(如你提供的 jqzcmqq1u0ossqae)。
  • exp (Expiration Time):過期時間(如你提供的 1774259594)。可以透過https://unixtime.bmcx.com/來獲取Unix 時間戳記 (Unix Timestamp)。它的定義是從 1970 年 1 月 1 日 00:00:00 UTC(稱為 Unix 紀元)起到現在所經過的 秒數
  • iat (Issued At):發行時間。
  • iss (Issuer):發行者(例如:ntub-auth-server)。
  • aud (Audience):接收者。

Private Claims

這是後端根據需求自定義的欄位,目的是讓前端不用再額外 call API 就能拿到基礎資訊。

{
  "sub": "jqzcmqq1u0ossqae",
  "exp": 1774259594,
  "role": "ADMIN",           // 你的 RoleContext 可能會用到
  "username": "王小明",       // 顯示在導覽列
  "dept": "IM"               // 資管系
}

Signature

signature 可以指一種Action也可以指一種Result。

簡單來說,當作為Action時,他是一個加密過程: ( Base64後的Header + Base64後的Payload ) × 你的Secret = Signature

而作為Result時,就是指這個運算後的結果。

Secret

secret是要保存在伺服器端的,這個secret一旦外洩給客戶端,客戶端就可以自己產生JWT,並且透過該JWT存取資源,因此secret是永遠不該外流的。

通常是一個亂碼字串,後端使用這串 Secret 透過演算法(如 HS256)對你的 Header 和 Payload 進行「簽名 (Signature)」。


JWT DoD

檢查項目準則為什麼?
禁止機密資訊絕對不可放密碼、身分證字號。JWT 只是 Base64 編碼,任何人都能解碼看到內容。
資料量精簡只放必要的欄位。每個請求都會帶這個 Token,Payload 太大會增加網路流量負載。
時效性設定exp 必須合理(如 1 小時)。防止 Token 被截獲後永久有效。
一致性欄位名稱與前端 interface 對齊。避免前端解碼後出現 undefined

PostMan