> For the complete documentation index, see [llms.txt](https://brianwu.gitbook.io/brian/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://brianwu.gitbook.io/brian/java/jwt.md).

# JWT

參考資料:(<https://jwt.io/introduction/>)

### 什麼是JSON Web令牌？

JSON Web 令牌（JWT）是一個開放標準（[RFC 7519](https://tools.ietf.org/html/rfc7519)），它定義了一種緊湊且自包含的方式，用於在各方之間作為JSON對象安全地傳輸信息。由於此信息是經過數字簽名的，因此可以被驗證和信任。可以使用密鑰（使用 **HMAC** 演算法）或使用 **RSA** 或 **ECDSA** 的公鑰/私鑰對對 JWT 進行**簽名**。

儘管可以對 JWT 進行加密以在雙方之間提供保密性，但我們將重點關注已*簽名的*令牌。簽名的令牌可以驗證其中包含的聲明的*完整性*，而加密的令牌則將這些聲明*隱藏*在其他方的面前。當使用公鑰/私鑰對對令牌進行簽名時，簽名還證明只有持有私鑰的一方才是對其進行簽名的一方。

### 什麼時候應該使用JSON Web令牌？

以下是JSON Web令牌有用的一些情況：

* **授權**：這是使用 JWT 的最常見方案。一旦用戶登錄，每個後續請求將包括 JWT，從而允許用戶訪問該令牌允許的路由，服務和資源。單一登錄是當今廣泛使用 JWT 的一項功能，因為它的開銷很小並且可以在不同的域中輕鬆使用。
* **信息交換**：JSON Web 令牌是在各方之間安全地傳輸信息的好方法。因為可以對 JWT 進行簽名（例如，使用公鑰/私鑰對），所以您可以確定發件人是他們所說的人。另外，由於簽名是使用標頭和有效負載計算的，因此您還可以驗證內容是否未被篡改。

### JSON Web令牌結構是什麼？

JSON Web令牌以緊湊的形式由三部分組成，這些部分由點（`.`）分隔，分別是：

* Header&#x20;
* Payload 有效載荷
* Signature 簽名

因此，JWT通常如下所示。

`xxxxx.yyyyy.zzzzz`

讓我們分解不同的部分。

#### 頭

標頭*通常*由兩部分組成：令牌的類型（即 JWT ）和所使用的簽名算法，例如 HMAC SHA256 或 RSA。

例如：

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

然後，此 JSON 被 **Base64Url** 編碼以形成 JWT 的第一部分。

#### 有效載荷

令牌的第二部分是有效負載，其中包含聲明。聲明是有關實體（通常是用戶）和其他數據的聲明。索賠有以下三種類型：*註冊的*，*公共的*和*私人*索賠。

* [**已註冊的權利要求**](https://tools.ietf.org/html/rfc7519#section-4.1)：這些是一組非強制性的但建議使用的預定義權利要求，以提供一組有用的，可互操作的權利要求。其中一些是： **iss**（發出者）， **exp**（到期時間）， **sub**（主題）， **aud**（受眾）[等](https://tools.ietf.org/html/rfc7519#section-4.1)。

  > 請注意，聲明名稱僅是三個字符，因為JWT是緊湊的。
* [**公共聲明**](https://tools.ietf.org/html/rfc7519#section-4.2)：使用JWT的人可以隨意定義這些聲明。但是為避免衝突，應在[ IANA JSON Web令牌註冊表](https://www.iana.org/assignments/jwt/jwt.xhtml)中定義它們，或將其定義為包含抗衝突名稱空間的URI。
* [**私人索賠**](https://tools.ietf.org/html/rfc7519#section-4.3)：這是創建共享使用它們同意並既不是當事人之間的信息自定義聲明*註冊*或*公眾*的權利要求。

有效負載示例可能是：

```
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
```

然後，對有效負載進行 **Base64Url** 編碼，以形成 JSON Web 令牌的第二部分。

> 請注意，對於已簽名的令牌，此信息儘管可以防止篡改，但任何人都可以讀取。除非將其加密，否則請勿將機密信息放入 JWT 的有效負載或報頭元素中。

**簽名**

要創建簽名部分，您必須獲取編碼的標頭，編碼的有效載荷，密鑰，標頭中指定的算法，並對其進行簽名。

例如，如果要使用 HMAC SHA256 算法，則將通過以下方式創建簽名：

```
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
```

簽名用於驗證消息在整個過程中沒有更改，並且對於使用私鑰進行簽名的令牌，它還可以驗證JWT的發送者是它所說的真實身份。

#### 放在一起

輸出是三個由點分隔的 Base64-URL 字符串，可以在 HTML 和 HTTP 環境中輕鬆傳遞這些字符串，與基於 XML 的標準（例如 SAML）相比，它更緊湊。

下圖顯示了一個 JWT，它已對先前的標頭和有效負載進行了編碼，並用一個密鑰進行了簽名。&#x20;

![編碼的JWT](https://cdn.auth0.com/content/jwt/encoded-jwt3.png)

如果您想使用JWT並將這些概念付諸實踐，則可以使用 [jwt.io Debugger](http://jwt.io/) 解碼，驗證和生成 JWT。

![JWT.io調試器](https://cdn.auth0.com/blog/legacy-app-auth/legacy-app-auth-5.png)

### JSON Web令牌如何工作？

在身份驗證中，當用戶使用其憑據成功登錄時，將返回 JSON Web 令牌。由於令牌是憑據，因此必須格外小心以防止安全問題。通常，令牌的保留時間不應超過要求的時間。

[由於缺乏安全性，](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#local-storage)您也不[應該將敏感的會話數據存儲在瀏覽器中](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#local-storage)。

每當用戶想要訪問受保護的路由或資源時，用戶代理通常應在 Header 中使用 Authorization 並結合 Bearer 和 JWT 。標頭的內容應如下所示：

```
Authorization: Bearer <token>
```

在某些情況下，這可以是無狀態授權機制。服務器的受保護路由將在`Authorization`標頭中檢查有效的 JWT ，如果存在，則將允許用戶訪問受保護的資源。如果 JWT 包含必要的數據，則可以減少查詢數據庫中某些操作的需求，儘管這種情況並非總是如此。

如果令牌是在`Authorization`標頭中發送的，則跨域資源共享（CORS）不會成為問題，因為它不使用 cookie。

下圖顯示瞭如何獲取JWT並將其用於訪問API或資源：

![JSON Web令牌如何工作](https://cdn2.auth0.com/docs/media/articles/api-auth/client-credentials-grant.png)

1. 應用程序或客戶端向授權服務器請求授權。這是通過不同的授權流程之一執行的。例如，典型的符合[OpenID Connect的](http://openid.net/connect/) Web應用程序將`/oauth/authorize`使用[授權代碼流](http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)通過端點。
2. 授予授權後，授權服務器會將訪問令牌返回給應用程序。
3. 應用程序使用訪問令牌來訪問受保護的資源（例如API）。

請注意，使用簽名令牌，令牌或令牌中包含的所有信息都會暴露給用戶或其他方，即使他們無法更改它。這意味著您不應將機密信息放入令牌中。

### 我們為什麼要使用JSON Web令牌？

讓我們談談與**簡單Web令牌（SWT）**&#x548C;**安全性聲明標記語言令牌（SAML）**&#x76F8;比，**JSON Web令牌（JWT）**&#x7684;好處。

由於JSON不如XML冗長，因此在編碼時JSON的大小也較小，從而使JWT比SAML更緊湊。這使得JWT是在HTML和HTTP環境中傳遞的不錯的選擇。

在安全方面，只能使用HMAC算法由共享機密對SWT進行對稱簽名。但是，JWT和SAML令牌可以使用X.509證書形式的公用/專用密鑰對進行簽名。與簽名JSON的簡單性相比，使用XML Digital Signature簽名XML而不引入模糊的安全漏洞是非常困難的。

JSON解析器在大多數編程語言中都很常見，因為它們直接映射到對象。相反，XML沒有自然的文檔到對象映射。與SAML斷言相比，這使使用JWT更加容易。

關於用法，JWT是在Internet規模上使用的。這強調了在多個平台（尤其是移動平台）上對JSON Web令牌進行客戶端處理的簡便性。

&#x20;*編碼的JWT和編碼的SAML的長度比較*

<div align="center"><img src="https://cdn.auth0.com/content/jwt/comparing-jwt-vs-saml2.png" alt="比較已編碼的JWT和已編碼的SAML的長度"></div>

如果您想了解有關JSON Web令牌的更多信息，甚至開始使用它們在自己的應用程序中執行身份驗證，請瀏覽到Auth0 上的[JSON Web令牌登錄頁面](http://auth0.com/learn/json-web-tokens)。
