动态

详情 返回 返回

JSON Web Token的理解 - 动态 详情

什麼是JWT?

JWT(JSON Web Token)是一種用於在各方之間安全地傳輸信息的緊湊、自包含的令牌格式。JWT是一種基於JSON的標準,定義了一種簡潔的方式來表示請求方和提供方之間的驗證信息。它通常用於Web應用的身份驗證和授權。

image.png

基於Session的認證流程

web服務離不開用户認證。一般流程是下面這樣。

image.png

Session存在的問題

  • 多台服務器共享問題:如果系統部署在多台服務器上(例如在負載均衡的情況下),每台服務器都需要能夠訪問所有的session數據。這就要求這些服務器之間共享session信息。

第一種解決方案

session複製,在這種方法中,每當用户的session在某台服務器上創建或更新時,session數據都會被複制到集羣中的其他服務器上。因此,無論用户的請求被負載轉發到哪台服務器,這些服務器都可以訪問相同的session數據

image.png
這樣對服務器不太友好,每個人只需要保存自己的 session id,而服務器要保存所有人的 session id !如果訪問服務器多了, 就得由成千上萬,甚至幾十萬個。

第二種解決方案

就是使用服務器來存儲session_id。這個想法是將所有的session數據集中存儲在這台服務器中,所有服務器都去訪問同一個存儲位置來獲取session數據。這樣一來,避免了在不同服務器之間複製session數據的麻煩。

image.png

這樣也存在一種問題,就是當這個session存儲的服務器掛了所以session全部失效,必須全部重新登錄

使用JWT

可以換種思路上,不一定需要進行存儲session,而是在存在客户端存儲,可是如果不保存這些 session id, 怎麼驗證客户端發給我的 session id 的確是我生成的呢,如果不去驗證,我們都不知道他們是不是合法登錄的用户。

JWT的結構

一個JWT通常由三部分組成:Header(頭部)、Payload(負載)和Signature(簽名),它們通過.分隔開來。

1. Header

Header通常包括兩部分:令牌類型(即JWT)和所使用的簽名算法(如HMAC SHA256或RSA)。Header的JSON形式如下:

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

將上述JSON數據進行Base64Url編碼後,得到JWT的第一部分。

2. Payload

Payload 部分也是一個 JSON 對象,用來存放實際需要傳遞的數據。JWT 規定了7個官方字段,供選用。

iss (issuer):簽發人
exp (expiration time):過期時間
sub (subject):主題
aud (audience):受眾
nbf (Not Before):生效時間
iat (Issued At):簽發時間
jti (JWT ID):編號

還可以定義私有字段

{
  "username": "mengyunzhi",
  "name": "yunzhi",
  "role": "admin"
}

JWT 默認是不加密的,任何人都可以讀到,所以不要把敏感信息(password或重要的個人身份信息)放在這個部分。

這個 JSON 對象也要使用 Base64URL 算法轉成字符串。

3. Signature

Signature 部分是對前兩部分的簽名,防止數據篡改。

首先,需要指定一個密鑰(secret)。這個密鑰只有服務器才知道,不能泄露給用户。然後,使用 Header 裏面指定的簽名算法(默認是 HMAC SHA256),按照下面的公式產生簽名。

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

算出簽名以後,把 Header、Payload、Signature 三個部分拼成一個字符串,每個部分之間用"點"(.)分隔,就可以返回給用户。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VybmFtZSI6Im1lbmd5dW56aGkiLCJuYW1lIjoieXVuemhpIiwicm9sZSI6ImFkbWluIn0.
Gecz5qFrimEVsxTIEvsgBvhEyyX2acr88YkT0ec-VGI

image.png

4. Base64URL

為什麼P要使用Base64URL進行加密算法

JWT 作為一個令牌(token),有時候會放上在 URL。Base64 有三個字符+、/和=,在 URL 裏面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。這就是 Base64URL 算法。

www.mengyunzhi.com/?token=xxxx

JWT 的使用方式

客户端收到服務器返回的 JWT,可以儲存在 Cookie 裏面,也可以儲存在 localStorage。

此後,客户端每次與服務器通信,都要帶上這個 JWT。一般是放在 HTTP 請求的頭信息Authorization字段裏面。

Authorization: Bearer <token>

總結

相比於傳統的基於Session的身份驗證方法,JWT具有以下幾個優勢:

無狀態:JWT不需要在服務器端存儲用户會話數據,令牌本身包含了所有必要的用户信息。

適用分佈式:由於JWT在客户端持有,而不依賴於服務器進行session存儲,因此在多個服務器或微服務之間傳遞用户身份信息時,JWT更為方便。

減少服務器負載:服務器不需要為每個用户維護Session數據,減輕了服務器的存儲壓力,特別是在大量用户同時訪問的情況下。

參考文章

https://learnku.com/articles/30051

Add a new 评论

Some HTML is okay.