首頁(yè)技術(shù)文章正文

JWT是什么?為什么JWT可以防止篡改?

更新時(shí)間:2023-03-16 來(lái)源:黑馬程序員 瀏覽量:

什么是JWT

JSON Web Token(JWT)是一種使用JSON格式傳遞數(shù)據(jù)的網(wǎng)絡(luò)令牌技術(shù),它是一個(gè)開放的行業(yè)標(biāo)準(zhǔn)(RFC 7519),它定義了一種簡(jiǎn)潔的、自包含的協(xié)議格式,用于在通信雙方傳遞json對(duì)象,傳遞的信息經(jīng)過(guò)數(shù)字簽名可以被驗(yàn)證和信任,它可以使用HMAC算法或使用RSA的公鑰/私鑰對(duì)來(lái)簽名,防止內(nèi)容篡改。官網(wǎng):https://jwt.io/

使用JWT可以實(shí)現(xiàn)無(wú)狀態(tài)認(rèn)證,那什么是無(wú)狀態(tài)認(rèn)證?

傳統(tǒng)的基于session的方式是有狀態(tài)認(rèn)證,用戶登錄成功將用戶的身份信息存儲(chǔ)在服務(wù)端,這樣加大了服務(wù)端的存儲(chǔ)壓力,并且這種方式不適合在分布式系統(tǒng)中應(yīng)用。

如下圖,當(dāng)用戶訪問應(yīng)用服務(wù),每個(gè)應(yīng)用服務(wù)都會(huì)去服務(wù)器查看session信息,如果session中沒有該用戶則說(shuō)明用戶沒有登錄,此時(shí)就會(huì)重新認(rèn)證,而解決這個(gè)問題的方法是Session復(fù)制、Session黏貼。
JWT令牌技術(shù)

如果是基于令牌技術(shù)在分布式系統(tǒng)中實(shí)現(xiàn)認(rèn)證則服務(wù)端不用存儲(chǔ)session,可以將用戶身份信息存儲(chǔ)在令牌中,用戶認(rèn)證通過(guò)后認(rèn)證服務(wù)頒發(fā)令牌給用戶,用戶將令牌存儲(chǔ)在客戶端,去訪問應(yīng)用服務(wù)時(shí)攜帶令牌去訪問,服務(wù)端從jwt解析出用戶信息。這個(gè)過(guò)程就是無(wú)狀態(tài)認(rèn)證。

JWT令牌技術(shù)

JWT令牌的優(yōu)點(diǎn):

1、jwt基于json,非常方便解析。

2、可以在令牌中自定義豐富的內(nèi)容,易擴(kuò)展。

3、通過(guò)非對(duì)稱加密算法及數(shù)字簽名技術(shù),JWT防止篡改,安全性高。

4、資源服務(wù)使用JWT可不依賴認(rèn)證服務(wù)即可完成授權(quán)。

缺點(diǎn):

1、JWT令牌較長(zhǎng),占存儲(chǔ)空間比較大。

下邊是一個(gè)JWT令牌的示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzMSJdLCJ1c2VyX
25hbWUiOiJ6aGFuZ3NhbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE2NjQyNTQ2NzI
sImF1dGhvcml0aWVzIjpbInAxIl0sImp0aSI6Ijg4OTEyYjJkLTVkMDUtNGMxNC1iY
mMzLWZkZTk5NzdmZWJjNiIsImNsaWVudF9pZCI6ImMxIn0.wkDBL7roLrvdBG2oGnX
eoXq-zZRgE9IVV2nxd-ez_oA

JWT令牌三大組成部分

JWT令牌由三部分組成,每部分中間使用點(diǎn)(.)分隔,比如:xxxxx.yyyyy.zzzzz

1. Header

頭部包括令牌的類型(即JWT)及使用的哈希算法(如HMAC SHA256或RSA) 一個(gè)例子如下:

下邊是Header部分的內(nèi)容

   {
    "alg": "HS256",
    "typ": "JWT"
  }

將上邊的內(nèi)容使用Base64Url編碼,得到一個(gè)字符串就是JWT令牌的第一部分。

2. Payload

第二部分是負(fù)載,內(nèi)容也是一個(gè)json對(duì)象,它是存放有效信息的地方,它可以存放jwt提供的信息字段,比如:iss(簽發(fā)者),exp(過(guò)期時(shí)間戳), sub(面向的用戶)等,也可自定義字段。

此部分不建議存放敏感信息,因?yàn)榇瞬糠挚梢越獯a還原原始內(nèi)容。

最后將第二部分負(fù)載使用Base64Url編碼,得到一個(gè)字符串就是JWT令牌的第二部分。

一個(gè)例子:

  {
    "sub": "1234567890",
    "name": "456",
    "admin": true
  }

3. Signature

第三部分是簽名,此部分用于防止jwt內(nèi)容被篡改。

這個(gè)部分使用base64url將前兩部分進(jìn)行編碼,編碼后使用點(diǎn)(.)連接組成字符串,最后使用header中聲明的簽名算法進(jìn)行簽名。

一個(gè)例子:

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

base64UrlEncode(header):jwt令牌的第一部分。

base64UrlEncode(payload):jwt令牌的第二部分。

secret:簽名所使用的密鑰。

為什么JWT可以防止篡改?

第三部分使用簽名算法對(duì)第一部分和第二部分的內(nèi)容進(jìn)行簽名,常用的簽名算法是 HS256,常見的還有md5,sha 等,簽名算法需要使用密鑰進(jìn)行簽名,密鑰不對(duì)外公開,并且簽名是不可逆的,如果第三方更改了內(nèi)容那么服務(wù)器驗(yàn)證簽名就會(huì)失敗,要想保證驗(yàn)證簽名正確必須保證內(nèi)容、密鑰與簽名前一致。

JWT加密防止篡改

從上圖可以看出認(rèn)證服務(wù)和資源服務(wù)使用相同的密鑰,這叫對(duì)稱加密,對(duì)稱加密效率高,如果一旦密鑰泄露可以偽造jwt令牌。

JWT還可以使用非對(duì)稱加密,認(rèn)證服務(wù)自己保留私鑰,將公鑰下發(fā)給受信任的客戶端、資源服務(wù),公鑰和私鑰是配對(duì)的,成對(duì)的公鑰和私鑰才可以正常加密和解密,非對(duì)稱加密效率低但相比對(duì)稱加密非對(duì)稱加密更安全一些。


分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!