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 Tokens由.
分隔的三個部分組成,它們是:npm
xxxxx.yyyyy.zzzzz
所示.標頭一般由兩部分組成:令牌的類型,即JWT,以及正在使用的簽名算法,例如HMAC SHA256或RSA。json
{
"alg": "HS256",
"typ": "JWT"
}
複製代碼
而後,這個JSON被編碼爲Base64Url,造成JWT的第一部分。跨域
令牌的第二部分是有效負載,其中包含聲明。聲明是關於實體(一般是用戶)和其餘數據的聲明。有三種類型:registered、public、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
複製代碼
在身份驗證中,當用戶使用其憑據成功登陸時,將返回JSON Web令牌。因爲令牌是憑證,所以必須很是當心以防止出現安全問題。通常狀況下,您不該該將令牌保留的時間超過要求。
每當用戶想要訪問受保護的路由或資源時,用戶代理應該使用承載模式發送JWT,一般在Authorization標頭中。標題的內容應以下所示:
Authorization: Bearer <token>
複製代碼
在某些狀況下,這能夠是無狀態受權機制。服務器的受保護路由將檢查Authorization標頭中的有效JWT ,若是存在,則容許用戶訪問受保護資源。若是JWT包含必要的數據,則能夠減小查詢數據庫以進行某些操做的須要,儘管可能並不是老是如此。
若是在標Authorization頭中發送令牌,則跨域資源共享(CORS)將不會成爲問題,由於它不使用cookie。
請注意,使用簽名令牌,令牌中包含的全部信息都會向用戶或其餘方公開,即便他們沒法更改。這意味着您不該該在令牌中放置祕密信息。
jsonwebtoken是json web token的實現
jwt.sign(payload, secretOrPrivateKey, [options, callback])
var jwt = require('jsonwebtoken');
var token = jwt.sign({ foo: 'bar' }, 'private-key',{ expiresIn: 1 *60 });
複製代碼
jwt.verify(token, secretOrPrivateKey, [options, callback])
jwt.verify(token, 'private-key', function(err, decoded) {
console.log('err:',err);
console.log('decoded:',decoded);
});
複製代碼