帶你走進 JSON Web Token

什麼是JSON Web Token?

JSON Web Token是一個開放標準(RFC 7519),它定義了一種緊湊且獨立的方式,用於在各方之間用JSON對象安全地傳輸信息。此信息能夠經過數字簽名進行驗證和信任。 JWT可使用加密算法(使用HMAC算法)或使用RSA或ECDSA的公鑰/私鑰對進行簽名。node

如下是JSON Web令牌有用的一些場景:web

  • 受權:這是使用JWT的最多見方案。一旦用戶登陸,每一個後續請求將包括JWT,容許用戶訪問該令牌容許的路由,服務和資源。 Single Sign On是一種如今普遍使用JWT的功能,由於它的開銷很小,而且可以在不一樣的域中輕鬆使用。算法

  • 信息交換:JSON Web令牌是在各方之間安全傳輸信息的好方法。由於JWT能夠簽名 - 例如,使用公鑰/私鑰對 - 您能夠肯定發件人是他們所說的人。此外,因爲使用標頭和有效負載計算簽名,您還能夠驗證內容是否未被篡改。數據庫

JSON Web令牌結構

JSON Web Tokens由.分隔的三個部分組成,它們是:npm

  • 有效載荷
  • 簽名 所以,JWT一般如xxxxx.yyyyy.zzzzz所示.

標頭一般由兩部分組成:令牌的類型,即JWT,以及正在使用的簽名算法,例如HMAC SHA256或RSA。json

{
  "alg": "HS256",
  "typ": "JWT"
}
複製代碼

而後,這個JSON被編碼爲Base64Url,造成JWT的第一部分。跨域

有效載荷

令牌的第二部分是有效負載,其中包含聲明。聲明是關於實體(一般是用戶)和其餘數據的聲明。有三種類型:registered、public、private claims.安全

  • registered:這些是一組預約義聲明,不是強制性的,但建議使用,以提供一組有用的,可互操做的聲明。其中一些是: iss(發行人), exp(到期時間),sub(主題), aud(觀衆)等。
  • public:這些能夠由使用JWT的人隨意定義。但爲避免衝突,應在 IANA JSON Web令牌註冊表中定義它們,或者將 其定義爲包含防衝突命名空間的URI。
  • private claims: 這是建立共享使用它們贊成並既不是當事人之間的信息自定義聲明註冊或公衆的權利要求

而後,有效負載通過Base64Url編碼,造成JSON Web令牌的第二部分。bash

請注意,對於簽名令牌,此信息雖然能夠防止被篡改,但任何人均可以讀取。除非加密,不然不要將祕密信息放在JWT的有效負載或頭元素中。服務器

簽名

要建立簽名部分,您必須採用編碼標頭,編碼的有效負載,祕密,標頭中指定的算法,並對其進行簽名。 例如,若是要使用HMAC SHA256算法,將按如下方式建立簽名:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
複製代碼

簽名用於驗證消息在此過程當中未被更改,而且,在使用私鑰簽名的令牌的狀況下,它還能夠驗證JWT的發件人是不是它所聲稱的人。

  • 結果

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

//原始
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1NjIxMzQ0MDIsImV4cCI6MTU2MjEzNDQ2Mn0.dzH7ogImjrWX8Qc-arXHFFjgF8YcO_KBi7BCgcmQUGk

//Base64 解碼後  
{"alg":"HS256","typ":"JWT"}{"foo":"bar","iat":1562134402,"exp":1562134462}�~耉��e�AϚ�q�8����b��rd

複製代碼

使用 jsonwebtoken 登陸

在身份驗證中,當用戶使用其憑據成功登陸時,將返回JSON Web令牌。因爲令牌是憑證,所以必須很是當心以防止出現安全問題。通常狀況下,您不該該將令牌保留的時間超過要求。

每當用戶想要訪問受保護的路由或資源時,用戶代理應該使用承載模式發送JWT,一般在Authorization標頭中。標題的內容應以下所示:

Authorization: Bearer <token>
複製代碼

在某些狀況下,這能夠是無狀態受權機制。服務器的受保護路由將檢查Authorization標頭中的有效JWT ,若是存在,則容許用戶訪問受保護資源。若是JWT包含必要的數據,則能夠減小查詢數據庫以進行某些操做的須要,儘管可能並不是老是如此。

若是在標Authorization頭中發送令牌,則跨域資源共享(CORS)將不會成爲問題,由於它不使用cookie。

請注意,使用簽名令牌,令牌中包含的全部信息都會向用戶或其餘方公開,即便他們沒法更改。這意味着您不該該在令牌中放置祕密信息。

node 中使用

jsonwebtoken是json web token的實現

生成JsonWebToken字符串

jwt.sign(payload, secretOrPrivateKey, [options, callback])

  • Returns: JsonWebToken字符串
  • payload:應該是表示有效JSON的對象文字,緩衝區或字符串。
  • secretOrPrivateKey : 是一個字符串,緩衝區或對象,包含HMAC算法的祕密或RSA和ECDSA的PEM編碼私鑰。若是是帶密碼的私鑰,則可使用對象{key,passphrase}(基於加密文檔),在這種狀況下,請確保傳遞算法選項。
var jwt = require('jsonwebtoken');

var token = jwt.sign({ foo: 'bar' }, 'private-key',{ expiresIn: 1 *60 });

複製代碼

驗證JsonWebToken字符串

jwt.verify(token, secretOrPrivateKey, [options, callback])

  • token: JsonWebToken string
  • secretOrPrivateKey : 是一個字符串,緩衝區或對象,包含HMAC算法的祕密或RSA和ECDSA的PEM編碼私鑰。若是是帶密碼的私鑰,則可使用對象{key,passphrase}(基於加密文檔),在這種狀況下,請確保傳遞算法選項。
jwt.verify(token, 'private-key', function(err, decoded) {
    console.log('err:',err);
    console.log('decoded:',decoded);
});
複製代碼
相關文章
相關標籤/搜索