最近在做項目時用到了使用JWT生成Token,原本不是很瞭解JWT。就這個機會,學習了一下,並記錄下來,以便以後參考。
那麼什麼是JWT呢?
JWT 是json web token 的簡稱。jwt其實就是一個字符串,主要由頭部、載荷和簽名三個部分組成。
類似如下字符串:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySWQiOjEyMywiVXNlck5hbWUiOiJhZG1pbiJ9.Qjw1epD5P6p4Yy2yju3-fkq28PddznqRj3ESfALQy_U
每個部分用英文點(.)號隔開。
頭部(header)
JWT的頭部位於該字符中第一部分,主要用來描述jwt的聲明類型和聲明加密方法的基礎信息。用json形式表示如下:
{
"typ":"JWT", //表示申聲明類型爲JWT
"alg":"HS256" //表示聲明的加密方法爲HS256
}
對這個json對象進行Base64加密,即可得到JWT頭部的字符串了,如下:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
載荷(payload)
載荷是JWT的核心,主要用來描述所存儲用戶的ID,失效時間等信息。服務端可以根據這些信息來判斷改token是哪個用戶已經登錄的證明了。這樣,服務端就可以不用保存任何信息,只要根據前段傳到後端的token就可以完成登錄鑑權功能。這一點與傳統服務端使用session保存用戶信息有本質的不同。
我們舉一個簡單的例子,使用json形式表示用戶的ID和失效時間:
{
"uid": "110110", //用戶Id
"exp": "14231234" //失效時間
}
同樣經過base64加密過後得到JWT的第二部分:
eyJ1aWQiOiAiMTEwMTEwIiwiZXhwIjogIjE0MjMxMjM0In0=
簽名(Signature)
簽名也是一個特殊的字符串,但是它不是向前兩部分一樣,將某個JSON串經過Base64加密過得到的字符串。簽名室友三個部分組成:
(1)經過base64加密過後的header:
base64UrlEncode(header) = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9;
(2)經過base64機密過後的payload:base64UrlEncode(payload) = eyJ1aWQiOiAiMTEwMTEwIiwiZXhwIjogIjE0MjMxMjM0In0=;
(3)secred
具體組成方式:將經過base64加密後的header與經過base64加密過後的payload用"."連接起來組成一個字符串,然後使用header中設置的加密方式(HS256),並使用secred(祕鑰)進行加密,這樣就得到了JWT的第三部分——簽名了。
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'key'); //這裏的祕鑰(secret)是字符串key
最終,將這三段字符串用"."連接起來,就得到了JWT.
總結:
通過使用JWT進行認真,具有以下幾點好處:
(1)首先相較於傳統的session方式,JWT不需要服務端保存信息,這樣減輕服務端開銷,同時易於擴展;
(2)JWT能輕鬆實現單點登錄,因爲認證信息已經保存到客戶端;
(3)能完成前後的分離;
(4)具有一定的安全性,這裏之所以說一定的,是因爲雖然JWT在載荷(payload)中使用了加密方法,但是其加密方法是能夠解密的,所以依舊不能夠將敏感信息保存到payload中。