[01-jwt]C# JWT基礎知識詳解

本文章內容翻譯自JWT官網,並融入了部分筆者的思想內容。希望給其他小夥伴在學習這部分內容時帶來一定的幫助。

一、什麼是JWT?

JWT是簡寫,全稱是JSON Web Token。

JSON Web Token(JWT)是一種開放標準(RFC 7519),它定義了一種緊湊(Compact)自包含(Self-contained)的方式,用於在各方之間以JSON對象的形式安全傳輸信息。此信息可以驗證和信任,因為它是經過數字簽名的。JWT可以使用密鑰(使用HMAC算法)或使用RSAECDSA的公鑰/私鑰對進行簽名。

下面進一步解釋這個定義中的一些概念:

·緊湊(Compact):由於它的大小,它可以通過 URL、POST 參數或 HTTP 標頭內部發送。此外,由於它的大小,它的傳輸速度很快。

·自包含(Self-contained):有效載荷(後面介紹)中包含有關用戶的所有必需信息,可以避免多次查詢數據庫。

雖然JWT可以加密以在各方之間提供保密性,但我們將重點專註於簽名令牌。簽名的令牌可以驗證其中包含的聲明的完整性,而加密的令牌會向其他方隱藏這些聲明。當使用公鑰/私鑰對對令牌進行簽名時,簽名還證明只有持有私鑰的一方才是簽署它的一方。

二、什麼時候應該使用 JSON Web Token?

以下是一些JSON Web token非常有用的場景:

  1. 授權(Authorization):這是使用JWT最常見的場景。用戶登錄後,每個後續請求都將包含JWT,從而允許用戶訪問該令牌允許的路由、服務和資源。單點登錄是當今廣泛使用JWT的一項功能,因為它的開銷很小,並且能夠在不同的域中輕鬆使用。
  2. 信息交換(Information Exchange):JSON Web Token是在各方之間安全傳輸信息的好方法。因為可以對 JWT 進行簽名(例如,使用公鑰/私鑰對),所以您可以確定發件人就是他們所說的那個人。此外,由於使用標頭和有效負載計算簽名,您還可以驗證內容沒有被篡改。

三、JSON Web Token 結構是什麼?

在其緊湊的形式中,JSON Web token由三部分組成,三部分由點(.)分隔,它們是:

  • 標頭(Header)
  • 有效載荷(Payload)
  • 簽名(Signature)

因此,JWT結構通常如下所示:

xxxxx.yyyyy.zzzzz

接下來,讓我們把不同的部分分解一下。

1、標頭(Header)

標頭通常由兩部分組成:

  1. 令牌的類型,即JWT
  2. 正在使用的簽名算法,例如HMAC SHA256或RSA。

例如:

{
    "alg": "HS256",  //簽名算法

    "typ": "JWT"  //類型
}

然後,這個 JSON 被Base64Url編碼以形成 JWT 的第一部分

2、有效載荷(Payload)

令牌的第二部分是有效載荷,其中包含聲明。聲明是關於實體(通常是用戶)和附加數據的陳述。聲明分為三種類型:

  1. 註冊(registered)聲明
  2. 公開(public)聲明
  3. 私有(private )聲明
  • 註冊聲明(Registered claims):這些是一組預定義的聲明,它們不是強制性的,但建議使用,以提供一組有用的、可互操作的聲明。其中一些是: iss(發行人) exp(到期時間) sub(主題)aud(受眾)等。
請注意,聲明名稱只有三個字符長,因為JWT是緊湊的。
  • 公開聲明(Public claims):這些可以由使用 JWT 的人隨意定義。但是為了避免衝突,它們應該在IANA JSON Web Token Registry中定義,或者定義為包含抗衝突命名空間的 URI。
  • 私人聲明(Private claims):這些是為在同意使用它們的各方之間共享信息而創建的自定義聲明,既不是註冊聲明也不是公共聲明。

一個有效載荷的示例可能是下面這個樣子:

{
    "iss": "xx網站",  //發行人

    "name": "張歐昊辰",  //全名

    "email": "[email protected]",   //郵箱

    "admin": true  //是否是管理員
}

然後,對有效負載進行Base64Url編碼以形成 JWT的第二部分

  • 請注意,對於已簽名的令牌,此信息雖然受到保護以防篡改,但任何人都可以讀取。除非已加密,否則請勿將機密信息放入 JWT 的有效負載或標頭元素中。

3、簽名(Signature)

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

例如,如果想使用 HMAC SHA256 算法,簽名將通過以下方式創建:

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

簽名用於驗證消息在此過程中沒有被更改,並且在使用私鑰簽名的令牌的情況下,它還可以驗證 JWT 的發送者就是它所說的那個人。

4、把所有的放在一起

輸出是三個用點分隔的 Base64-URL 字符串,可以在 HTML 和 HTTP 環境中輕鬆傳遞,同時與基於 XML 的標準(如 SAML)相比更緊湊。

下面顯示了一個 JWT,該 JWT 具有先前的標頭和有效負載編碼,並使用密鑰簽名。

四、JSON Web Token是如何工作?

在身份驗證中,當用戶使用其憑據成功登錄時,將返回一個 JSON Web Token。由於令牌是憑據,因此必須非常小心以防止出現安全問題。通常,不應將令牌保留超過所設置的過期時間。

由於缺乏安全性,也不應該在瀏覽器存儲中存儲敏感的會話數據。

每當用戶想要訪問受保護的路由或資源時,用戶代理應該發送 JWT,通常在Authorization標頭中使用Bearer模式。

標頭的內容應如下所示:

Authorization: Bearer <token>

在某些情況下,這可以是一種無狀態授權驗證機制,因為用戶狀態永遠不會保存在服務器內存中。服務器的受保護路由將檢查Authorization標頭中是否存在有效的 JWT,如果存在,則允許用戶訪問受保護的資源。由於 JWT 是自包含的,所有必要的信息都在那裡,減少了返回和轉發到數據庫的需要。

這允許完全依賴無狀態的數據 API,甚至可以向下游服務發出請求。如果令牌在Authorization標頭中發送,則跨域資源共享 (CORS) 不會成為問題,因為它不使用 cookie。

JSON Web 令牌的工作原理

特別注意,使用簽名令牌時,令牌中包含的所有信息都會向用戶或其他方公開,即使他們無法更改,這也意味着不應將秘密信息放入令牌中。

五、為什麼我們應該使用 JSON Web Tokens?

下面我們談一談JSON Web Tokens (JWT)Simple Web Tokens (SWT)Security Assertion Markup Language Tokens (SAML)相比的優勢。

  1. 由於 JSON 不像 XML 那樣冗長,因此在對其進行編碼時,它的大小也更小,這使得 JWT 比 SAML 更緊湊。這使得 JWT 成為在 HTML 和 HTTP 環境中傳遞的不錯選擇。
  2. 安全方面,SWT 只能通過使用 HMAC 算法的共享密鑰進行對稱簽名。但是,JWT 和 SAML 令牌可以使用 X.509 證書形式的公鑰/私鑰對進行簽名。與簽署 JSON 的簡單性相比,使用 XML 數字簽名簽署 XML 而不引入隱蔽的安全漏洞是非常困難的。
  3. JSON 解析器在大多數編程語言中都很常見,因為它們直接映射到對象。相反,XML 沒有自然的文檔到對象映射。這使得使用 JWT 比使用 SAML 斷言更容易。
  4. 關於使用,JWT 用於 Internet 規模。這突出了 JSON Web Token在多個平台(尤其是移動平台)上客戶端處理的便利性。

 下圖為編碼的 JWT 和編碼的 SAML 的長度比較

比較編碼的 JWT 和編碼的 SAML 的長度


The End……