一、認證機制
1. Cookie-Sesion
A. cookie-session認證機制是為一次請求認證在服務端創建一個session對象,同時在客戶端的瀏覽器創建一個cookie對象,通過客戶端帶上來的cookie對象與服務端的session對象匹配來實現狀態管理的;
B. 缺點:每個用戶經過我們的應用認證之后,都會在服務端做一次記錄,以方便用戶下次請求的鑒別,一般session都是保存在內存中,而隨着認證用戶的增多,服務端開銷會明顯增大;
如果認證信息(session)是被保存在內存中,這意味着用戶下次請求還必須要發到這台服務器上,這樣才能拿到授權的資源,對於分布式應用,則限制了負載均衡器的能力,不易擴展;
通過cookie來進行用戶識別,如果cookie被捕獲,服務器就會很容易受到跨站請求偽造的攻擊(CSRF)。
2. JWT Token
A. JWT是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON標准,JWT的聲明一般被用在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便與從資源服務器獲取資源,也可以增加一些額外的其他業務邏輯所必須的聲明信息,服務器不會保存任何會話狀態,即服務器無狀態;
B. 特點:體積小,因而傳輸速度快;
傳輸方式多樣,如URL/POST參數/HTTP頭部等方式傳輸;
嚴格的結構化,在payload中包含了所有與用戶相關的驗證消息,如用戶可訪問路由、訪問有效期等信息,服務器無需再去連接數據庫驗證信息的有效性,並且payload支持為應用定制化。
二、JWT(JSON Web Token)
1. JWT組成結構
A. Header(頭部):JSON對象,用來描述JWT的元數據,最后用Base64URL算法將其轉化為字符串;
{
"alg": "HS256", // algorithm,簽名的算法,默認是HMAC SHA256
"typ": "JWT" // type,令牌的類型,JWT令牌統一寫成JWT
}
B. Payload(載荷內容):也是JSON對象,用來存放主體內容的地方,包含要傳遞的數據,由標准中注冊的聲明、公共的聲明和私有的聲明三部分構成,最后也用Base64URL算法將其轉化為字符串;
標准中注冊的聲明:
{
"iss": // issuer,簽發者
"sub": // subject,主題
"aud": // audience,接收JWT的一方
"exp": // expiration time,JWT的過期時間
"nbf": // Not Before,生效時間,在此之前不可用
"iat": // Issued At,簽發時間
"jti": // JWT ID,JWT唯一身份標識,主要用作一次性token,避免重放攻擊
}
公共的聲明:一般添加用戶的相關信息或其他業務需要的必要信息,不要添加敏感信息,因為base64是對稱加密,可解密的;
私有的聲明:是提供者與消費者所共同自定義的聲明,也不要添加敏感信息;
C .Signature(簽名):是由Base64URL后的header和payload,再加上秘鑰secret進行算法(默認HMAC SHA256)加密構成的,秘鑰僅僅保存在服務器中;
由於簽名是對頭部和載荷內容進行簽名,如果有人對頭部以及載荷的內容解碼之后進行修改,再編碼的話,加上未知的私鑰,那么新的簽名和之前的就不一樣,這樣能保證token不被篡改,這是JWT安全機制;
另外Base64URL是Base64算法基礎上將三個字符變換下,"="去掉,"+"用"-"替換,"/"用"_"替換;
綜合:Token就是將頭部、載荷內容和簽名的這三部分用點符號連接形成的JWT,如:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NzgwMjc4ODksInVzZXJuYW1lIjoiYWRtaW4ifQ.uE-Nhr1C_gXVxYUdWik9T6_rIY9KLDYePddXbfvXNFs
2. JWT用法
A. 前端:Authorization: Bearer token 客戶端接收服務器返回的token,可存儲在localStorage中,每次客戶端與服務器交互都需要攜帶;
B. 后端:用戶請求登錄服務器 ->服務器接收到請求生成jwt token並返回 ->用戶請求攜帶token認證 ->認證通過接着后面的請求,認證不通過,前端重置登錄頁面。
3. JWT優缺點
A. 優點:是無狀態會話解決方案之一,支持跨域驗證,特別適用於分布式站點單點登錄,還可用於信息交換,用來減少與數據庫交互的次數;
B. 缺點:由於服務器不保存會話狀態,所以使用期間不可能取消令牌或更改令牌權限,也就是一旦JWT簽發,在有效期內將會一直有效;
C. 針對令牌簽發無法作廢的問題可以借助其他辦法解決,如使用redis存儲信息,作廢時刪除信息,校驗token時結合二者一起判斷。