一起重新全面認識JWT-Json Web Token
概述
最近學習了一下JWT,全名為Json Web Token,是一種自包含令牌。
在這裡,我整理了一下網上資源。在文章最後,有一個使用Java實作JWT生成和驗證的完整案例。
簡單的說,就是基于JSON,在web環境下傳輸一個規定格式的字元串令牌。
廣義上講JWT,這是一個Web安全傳輸資訊方式。狹義上來說,直接指傳遞的令牌字元串。
JWT官網位址:
https://jwt.io/,在這裡,你可以體驗一下形成的JWT字元串。

應用場景
首先,我們需要知道,JWT無法用于資料加密。一般是用來身份提供者和服務者之間傳遞被認證的使用者身份資訊,以便于從資源伺服器擷取到資源。
也可以增加一些額外的其它業務邏輯所必須的聲明資訊,該token也可直接被用于認證,也可被加密。
是以,可以推斷出,在以下場景中使用JWT是比較合适的。
- 授權:這是最常見的使用場景,解決單點登入問題。因為JWT使用起來輕便,開銷小,服務端不用記錄使用者狀态資訊(無狀态),是以使用比較廣泛;
- 資訊交換:JWT是在各個服務之間安全傳輸資訊的好方法。因為JWT可以簽名,例如,使用公鑰/私鑰對兒 - 可以确定請求方是合法的。此外,由于使用标頭和有效負載計算簽名,還可以驗證内容是否未被篡改。
JWT認證過程
JWT官網有一張圖描述了JWT的認證流程
流程說明:
- 1,浏覽器發起請求登陸,攜帶使用者名和密碼;
- 2,服務端驗證身份,根據算法,将使用者辨別符打包生成 token,
- 3,伺服器傳回JWT資訊給浏覽器,JWT不包含敏感資訊;
- 4,浏覽器發起請求擷取使用者資料,把剛剛拿到的 token一起發送給伺服器;
- 5,伺服器發現資料中有 token,驗明正身;
- 6,伺服器傳回該使用者的使用者資料;
JWT的資料結構
JWT字元串的格式:
header.payload.signature
JWT通常由三部分組成,按照順序: 頭資訊(header), 有效載荷(payload)和簽名(signature)。
header
header是一串描述JWT中繼資料的JSON字元串,例如:
{"alg":"HS256","typ":"JWT"}
HS256 表示使用了 HMAC-SHA256 來生成簽名。
最後使用Base64URL算法将上述JSON對象轉換為字元串儲存。
其他還有一些簽名算法,可以去官網檢視。
payload
Payload 部分也是一個 JSON 對象,用來存放實際需要傳遞的資料。JWT 規定了7個官方字段,供選用。
iss (issuer):簽發人
exp (expiration time):過期時間(jwt的過期時間,這個過期時間必須要大于簽發時間)
sub (subject):主題
aud (audience):閱聽人
nbf (Not Before):生效時間(定義在什麼時間之前,該jwt都是不可用的.)
iat (Issued At):簽發時間
jti (JWT ID):編号(jwt的唯一身份辨別,主要用來作為一次性token,進而回避重播攻擊。)
當然,除了前面的字元串,這裡也就是我們傳輸資料的地方。可以自定義字段傳輸。例如:
{
"微信公衆号": "程式程式設計之旅",
"姓名": "谙憶"
}
當然,我這裡就是推廣下公衆号,前面的key用了中文名,你别這麼玩就行。
注意哦,這部分的資料預設是不加密的。是以,如果有敏感資訊,注意再使用加密算法把資料加密後傳輸即可。
這個JSON對象傳輸時,也要使用Base64URL算法轉成字元串。
signature
簽名哈希部分是對上面兩部分資料簽名,通過指定的算法生成哈希,以確定資料不會被篡改。
首先,需要指定一個密碼(secret)。該密碼儲存在伺服器中,并且不能向使用者公開。然後,使用标頭中指定的簽名算法(預設情況下為HMAC SHA256)根據以下公式生成簽名。
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
token看起來像這樣:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI
JWT的用法
用戶端接收伺服器傳回的JWT,将其存儲在Cookie或localStorage中。
此後,用戶端将在與伺服器互動中都會帶JWT。如果将它存儲在Cookie中,就可以自動發送,但是不會跨域,是以一般是将它放入HTTP請求的Header Authorization字段中。
當跨域時,也可以将JWT放置于POST請求的資料主體中。
JWT的優缺點
1、JWT預設不加密,是以可能導緻資料洩露,但可以加密。生成原始令牌後,可以使用該令牌再次對其進行加密。
2、當JWT未加密時,一些私密資料無法通過JWT傳輸。
3、JWT不僅可用于認證,還可用于資訊交換。善用JWT有助于減少伺服器請求資料庫的次數。
4、JWT的最大缺點是伺服器不儲存會話狀态,是以在使用期間不可能取消令牌或更改令牌的權限。也就是說,一旦JWT簽發,在有效期内将會一直有效。
5、JWT本身包含認證資訊,是以一旦資訊洩露,任何人都可以獲得令牌的所有權限。為了減少盜用,JWT的有效期不宜設定太長。對于某些重要操作,使用者在使用時應該每次都進行身份驗證。
6、為了減少盜用和竊取,JWT不建議使用HTTP協定來傳輸代碼,而是使用加密的HTTPS協定進行傳輸,防止伺服器傳回給使用者的JWT被攔截。
看着上面6點,我的建議是,無論有沒有敏感資料,對于使用者認證資訊資料做一層加密。最大程度上避免資料洩露造成問題。
最後,強調一點:JWT不是用來加密的,隻是用來驗證使用者的真實性以及請求來源的真實性。
最後
希望大家能動動手指,關注公衆号:程式程式設計之旅
關注即可加入技術交流群。更多技術,更多故事,更多精彩内容等您來看。