聊聊JWT

深夜程猿發表於2018-09-26

隨著前後端分離越來越普及,傳統的基於cookie-session的鑑權方式已經不適用於前後端分離專案了。在鑑權方面,有許多的實現方式,這篇文章不是來對比和介紹各個鑑權方式的優缺點,而是來普及其中之一-JWT。

更多文章,歡迎關注微信公眾號:深夜程猿。

JWT工作原理圖

什麼是JWT

JWT是JSON Web Token的縮寫。 JSON Web Token(JWT)是一個開放標準(RFC 7519),它定義了一種緊湊且獨立的方式,可以在各方之間作為JSON物件安全地傳輸資訊。此資訊可以通過數字簽名進行驗證和信任。 JWT可以使用加密演算法(例如HMAC演算法)或使用RSA或ECDSA的公鑰/私鑰對進行簽名。 雖然JWT可以加密以在各方之間提供保密,但我們將專注於簽名令牌。簽名令牌可以驗證其中包含的宣告的完整性,而加密令牌則隱藏其他方的宣告。當使用公鑰/私鑰對簽署令牌時,簽名還證明只有持有私鑰的一方是簽署私鑰的一方。

JWT的結構

JWT由三部分組成,使用'.'號連線:

  • Header部分 標頭通常由兩部分組成:令牌的型別,即JWT,以及正在使用的雜湊演算法,例如HMAC SHA256或RSA。,比如{ "alg": "HS256", "typ": "JWT" }表示使用了HS256來生成簽名。Header部分會使用Base64Url編碼設定到JWT的第一部分。
  • Payload部分: 令牌的第二部分是有效負載,其中包含宣告。宣告是關於實體(通常是使用者)和其他資料的宣告。宣告有三種型別:註冊,公開和私有宣告。
    註冊宣告:這些是一組預定義的宣告,它們不是強制性的,但是建議使用,以提供一組有用的,可互操作的宣告。其中一些是:iss(發行人),exp(到期時間),sub(主題),aud(觀眾)等。
    公開宣告:這些可以由使用JWT的人隨意定義。但是為避免衝突,應在IANA JSON Web令牌登錄檔中定義它們,或者將其定義為包含防衝突名稱空間的URI。
    私有宣告:這些是為在同意使用它們的各方之間共享資訊而建立的自定義宣告,既不是註冊宣告也不是公開宣告。
    一個Payload示例:
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
 }
複製程式碼
Payload也會和Header一樣Base64Url編碼,放在JWT第二部分。
複製程式碼
  • Signature部分: 要建立簽名部分,必須採用編碼標頭(Header),編碼的有效負載(Payload),祕鑰,標頭中指定的演算法,並對其進行簽名。 例如,如果要使用HMAC SHA256演算法,將按以下方式建立簽名:
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
複製程式碼

最後用'.'號把三個部分連線起來就完成了一個完整的JWT。

JWT的用途

認證

這是使用JWT的最常見場景。一旦使用者登入,每個後續請求將包括JWT,允許使用者訪問該令牌允許的路由,服務和資源。 單點登入是一種現在廣泛使用JWT的功能,因為它的開銷很小,並且能夠在不同的域中輕鬆使用

資訊交換

JSON Web Token是在各方之間安全傳輸資訊的好方法。因為JWT可以簽名 - 例如,使用公鑰/私鑰對 - 您可以確定發件人是他們所說的人。此外,由於使用標頭和有效負載計算簽名,您還可以驗證內容是否未被篡改。

JWT工作原理

在身份驗證中,當使用者使用其憑據成功登入時,將返回JSON Web令牌。由於令牌是憑證,因此必須非常小心以防止出現安全問題。一般情況下,您不應該將令牌保留的時間超過要求。 每當使用者想要訪問受保護的路由或資源時,使用者代理應該使用承載模式傳送JWT,通常在Authorization標頭中。標題的內容應如下所示:

Authorization: Bearer <token>
複製程式碼

在某些情況下,這可以是無狀態授權機制。伺服器的受保護路由將在Authorization標頭中檢查有效的JWT,如果存在,則允許使用者訪問受保護的資源。如果JWT包含必要的資料,則可以減少查詢資料庫以進行某些操作的需要,儘管可能並非總是如此。 如果在Authorization標頭中傳送令牌,則跨域資源共享(CORS)將不會成為問題,因為它不使用cookie。 下圖顯示瞭如何獲取JWT並用於訪問API或資源:

JWT工作原理圖

  1. 應用程式或客戶端向授權伺服器請求授權。這是通過其中一個不同的授權流程執行的。例如,典型的OpenID Connect相容Web應用程式將使用授權程式碼流通過/ oauth / authorize端點。
  2. 授予授權後,授權伺服器會嚮應用程式返回訪問令牌。
  3. 應用程式使用訪問令牌來訪問受保護資源(如API)。 由於JWT會暴露給第三方和使用者,所以在生成JWT的時候我們最好不要把使用者隱私資料放進去。

參考連結:Introduction to JSON Web Tokens