Json web token(JWT)是爲了網絡應用環境間傳遞聲明而執行的一種基於JSON的開發標準(RFC 7519),該token被設計爲緊湊且安全的,特別適用於分佈式站點的單點登錄(SSO)場景。JWT的聲明通常被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也能夠增長一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。git
咱們知道http協議是無狀態的,一般咱們爲了進行用戶認證,流程大概以下:github
1.客戶端發送用戶名和密碼給服務器;
2.服務器接驗證經過後,會將當前會話(session)中保存用戶信息;
3.服務器向客戶端發送一個session_id做爲會話憑證,並寫入cookie;
4.用戶每次請求從cookie中獲取session_id併發送給服務器;
5.服務器驗證session_id,web
session認證的缺點:算法
難以拓展 用戶認證以後,服務端作認證記錄,若是認證的記錄被保存在內存的話,這意味着用戶下次請求還必需要請求在這臺服務器上,這樣才能拿到受權的資源,這樣在分佈式的應用上,響應的限制了負載均衡器的能力,也意味着限制了應用的擴展性。json
CSRF 由於是基於cookie來進行用戶識別的,cookie若是被截獲,用戶就會很容易受到跨站請求僞造的攻擊。api
基於token的鑑權機制相似於http協議也是無狀態的,它不須要在服務端去保留用戶的認證信息或會話信息。這也就意味着機遇tokent認證機制的應用不須要去考慮用戶在哪一臺服務器登錄了,這就爲應用的擴展提供了便利。安全
這個token必需要在每次請求時發送給服務器,它應該保存在請求頭中,另外,服務器要支持CORS(跨來源資源共享)策略,通常咱們在服務端這麼作就能夠了 Access-Control-Allow-Origin:*bash
JWT是由三部分構成,將這三段信息文本用連接構成了JWT字符串。就像這樣服務器
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJVc2VySWQiOjEyMywiVXNlck5hbWUiOiJhZG1pbiJ9.
Qjw1epD5P6p4Yy2yju3-fkq28PddznqRj3ESfALQy_U
複製代碼
第一部分咱們稱它爲頭部(header)第二部分咱們稱其爲載荷(payload,相似於飛機上承載的物品),第三部分是簽證(signature)cookie
Header
JWT的頭部承載的兩部分信息:
{
'typ':'JWT',
'alg':'HS256'
}
複製代碼
而後將頭部進行base64加密(該加密是能夠對稱解密的),構成了第一部分
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
複製代碼
plyload
Payload 部分也是一個 JSON 對象,用來存放實際須要傳遞的數據。JWT 規定了7個官方字段,供選用。
Signature
Signature 部分是對前兩部分的簽名,防止數據篡改。
首先,須要指定一個密鑰(secret)。這個密鑰只有服務器才知道,不能泄露給用戶。而後,使用 Header 裏面指定的簽名算法(默認是 HMAC SHA256),按照下面的公式產生簽名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
複製代碼
注意:secret是保存在服務器端的,jwt的簽發也是在服務端的,secret就是用來進行jwt的簽發和jwt的驗證,因此它就是你服務端的私鑰,在任何場景都不該該流露出去,一旦客戶端得知這個secret,那就意味着客戶端能夠自我簽發jwt了
通常是在請求頭裏加入Authorization,並加上Bearer標註:
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer ' + token
}
})
複製代碼