🎫
← 返回教學列表

JWT 權杖結構詳解:標頭、有效載荷與簽名

· 標籤: jwt-structure, jwt-header, jwt-payload, jwt-signature, json-web-token

JWT 權杖結構詳解

每個 JSON Web Token(JWT)都是一個簡潔、URL 安全的字串,用於在兩方之間傳遞聲明(claims)。了解其內部結構對於任何從事基於權杖安全開發的工程師來說至關重要。

JWT 的三個部分

一個 JWT 由三個以點號(.)分隔的部分組成:

header.payload.signature

範例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

每個部分都是經過 base64url 編碼的 JSON。JWT 是簽名的,而非加密的 — 任何人都可以解碼並讀取其內容。

第一部分:標頭(Header)

標頭包含關於權杖的元資料 — 簽名演算法和權杖類型。

| 欄位 | 描述 | 範例值 | |-------|------|----------| | alg | 簽名演算法(必填) | HS256RS256ES256 | | typ | 權杖類型(選填) | JWT | | kid | 金鑰 ID(選填) | "key-1" |

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

alg 欄位告知驗證器使用哪個演算法來建立簽名。演算法不匹配 — 或接受 alg: "none" — 是常見的 JWT 安全漏洞。

第二部分:有效載荷(Payload)

有效載荷包含關於使用者及元資料的聲明(claims)。聲明分為三類:

註冊聲明(Registered Claims)

| 聲明 | 全名 | 用途 | |------|------|------| | iss | Issuer(簽發者) | 誰簽發了此權杖 | | sub | Subject(主體) | 識別使用者 | | aud | Audience(受眾) | 預期接收者 | | exp | Expiration(過期時間) | 權杖過期時間戳 | | nbf | Not Before(生效時間) | 權杖在此時間之前無效 | | iat | Issued At(簽發時間) | 權杖建立時間戳 | | jti | JWT ID(JWT 識別碼) | 唯一的權杖識別碼 |

解碼後的有效載荷範例

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622,
  "iss": "https://auth.example.com"
}

公開聲明(Public claims)在 IANA 註冊表中定義,或使用避免衝突的 URI。私有聲明(Private claims)是簽發者與消費者之間約定的自訂聲明。

第三部分:簽名(Signature)

簽名是通過使用標頭中指定的演算法,將編碼後的標頭、編碼後的有效載荷和密鑰組合在一起而建立的。它有兩個目的:

  1. 完整性 — 確認權杖在簽名後未被修改。
  2. 身份驗證 — 證明權杖是由預期的一方簽名的。

HS256 簽名建立

HMACSHA256(
  base64urlEncode(header) + "." + base64urlEncode(payload),
  secret
)

RS256 簽名建立

RSASHA256(
  base64urlEncode(header) + "." + base64urlEncode(payload),
  privateKey
)

Base64url 與標準 Base64 的比較

| 方面 | 標準 Base64 | Base64url | |------|-------------|-----------| | 第 62 個字元 | + | - | | 第 63 個字元 | / | _ | | 填充 | = | 省略 |

這種編碼方式確保 JWT 可以安全地用於 HTTP 標頭、查詢參數和 URL 路徑,無需進行百分比編碼。

完整的 JWT 建立流程

  1. 建立標頭 JSON 並進行 base64url 編碼。
  2. 建立有效載荷 JSON 並進行 base64url 編碼。
  3. . 分隔符連接。
  4. 使用所選的演算法和密鑰進行簽名。
  5. 對簽名進行 base64url 編碼。
  6. . 分隔符連接全部三個部分。

安全考量

  • 切勿將密鑰存放在有效載荷中。 有效載荷是編碼的,而非加密的。
  • 始終驗證簽名。 若不驗證,任何人都可以偽造權杖。
  • 檢查 alg 標頭。 拒絕 alg: "none" 和演算法降級攻擊。
  • 設定較短的過期時間。 使用 exp 聲明,以分鐘或小時為單位,而非數月。

線上解碼 JWT 權杖

使用 JWT 解碼器工具來檢查任何權杖。貼上權杖,即可立即查看解碼後的標頭、有效載荷和簽名演算法。所有處理都在你的瀏覽器中完成。

JWT 權杖結構詳解:標頭、有效載荷與簽名 - CoolTool