更新時間:2023-03-16 來源:黑馬程序員 瀏覽量:
JSON Web Token(JWT)是一種使用JSON格式傳遞數(shù)據(jù)的網(wǎng)絡令牌技術(shù),它是一個開放的行業(yè)標準(RFC 7519),它定義了一種簡潔的、自包含的協(xié)議格式,用于在通信雙方傳遞json對象,傳遞的信息經(jīng)過數(shù)字簽名可以被驗證和信任,它可以使用HMAC算法或使用RSA的公鑰/私鑰對來簽名,防止內(nèi)容篡改。官網(wǎng):https://jwt.io/
使用JWT可以實現(xiàn)無狀態(tài)認證,那什么是無狀態(tài)認證?
傳統(tǒng)的基于session的方式是有狀態(tài)認證,用戶登錄成功將用戶的身份信息存儲在服務端,這樣加大了服務端的存儲壓力,并且這種方式不適合在分布式系統(tǒng)中應用。
如下圖,當用戶訪問應用服務,每個應用服務都會去服務器查看session信息,如果session中沒有該用戶則說明用戶沒有登錄,此時就會重新認證,而解決這個問題的方法是Session復制、Session黏貼。
如果是基于令牌技術(shù)在分布式系統(tǒng)中實現(xiàn)認證則服務端不用存儲session,可以將用戶身份信息存儲在令牌中,用戶認證通過后認證服務頒發(fā)令牌給用戶,用戶將令牌存儲在客戶端,去訪問應用服務時攜帶令牌去訪問,服務端從jwt解析出用戶信息。這個過程就是無狀態(tài)認證。
1、jwt基于json,非常方便解析。
2、可以在令牌中自定義豐富的內(nèi)容,易擴展。
3、通過非對稱加密算法及數(shù)字簽名技術(shù),JWT防止篡改,安全性高。
4、資源服務使用JWT可不依賴認證服務即可完成授權(quán)。
缺點:
1、JWT令牌較長,占存儲空間比較大。
下邊是一個JWT令牌的示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzMSJdLCJ1c2VyX 25hbWUiOiJ6aGFuZ3NhbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE2NjQyNTQ2NzI sImF1dGhvcml0aWVzIjpbInAxIl0sImp0aSI6Ijg4OTEyYjJkLTVkMDUtNGMxNC1iY mMzLWZkZTk5NzdmZWJjNiIsImNsaWVudF9pZCI6ImMxIn0.wkDBL7roLrvdBG2oGnX eoXq-zZRgE9IVV2nxd-ez_oA
JWT令牌由三部分組成,每部分中間使用點(.)分隔,比如:xxxxx.yyyyy.zzzzz
頭部包括令牌的類型(即JWT)及使用的哈希算法(如HMAC SHA256或RSA) 一個例子如下:
下邊是Header部分的內(nèi)容
{ "alg": "HS256", "typ": "JWT" }
將上邊的內(nèi)容使用Base64Url編碼,得到一個字符串就是JWT令牌的第一部分。
第二部分是負載,內(nèi)容也是一個json對象,它是存放有效信息的地方,它可以存放jwt提供的信息字段,比如:iss(簽發(fā)者),exp(過期時間戳), sub(面向的用戶)等,也可自定義字段。
此部分不建議存放敏感信息,因為此部分可以解碼還原原始內(nèi)容。
最后將第二部分負載使用Base64Url編碼,得到一個字符串就是JWT令牌的第二部分。
一個例子:
{ "sub": "1234567890", "name": "456", "admin": true }
第三部分是簽名,此部分用于防止jwt內(nèi)容被篡改。
這個部分使用base64url將前兩部分進行編碼,編碼后使用點(.)連接組成字符串,最后使用header中聲明的簽名算法進行簽名。
一個例子:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
base64UrlEncode(header):jwt令牌的第一部分。
base64UrlEncode(payload):jwt令牌的第二部分。
secret:簽名所使用的密鑰。
第三部分使用簽名算法對第一部分和第二部分的內(nèi)容進行簽名,常用的簽名算法是 HS256,常見的還有md5,sha 等,簽名算法需要使用密鑰進行簽名,密鑰不對外公開,并且簽名是不可逆的,如果第三方更改了內(nèi)容那么服務器驗證簽名就會失敗,要想保證驗證簽名正確必須保證內(nèi)容、密鑰與簽名前一致。
從上圖可以看出認證服務和資源服務使用相同的密鑰,這叫對稱加密,對稱加密效率高,如果一旦密鑰泄露可以偽造jwt令牌。
JWT還可以使用非對稱加密,認證服務自己保留私鑰,將公鑰下發(fā)給受信任的客戶端、資源服務,公鑰和私鑰是配對的,成對的公鑰和私鑰才可以正常加密和解密,非對稱加密效率低但相比對稱加密非對稱加密更安全一些。