cookie、session和jwt

概要

cookie

1. 爲何會出現cookie?web

http是無狀態的協議,致使請求不知道是哪一個用戶操做的。cookie的出現就是爲了解決http請求無狀態和服務端要知道請求來源之間的矛盾。算法

cookie會根據服務端發送的響應報文中的set-cookie字段信息,通知客戶端保存cookie。下次客戶端發送請求時就會攜帶cookie,服務端收到請求,根據cookie和服務器的記錄進行比對,找到以前的狀態。數據庫

2. cookie存在的問題有哪些?json

  • cookie會做爲http的請求報文進行傳遞,因此要注意cookie字段的大小,通常小於4kb。若是cookie存儲的字段過大,浪費流量,服務端也會耗費性能解析cookie。跨域

  • cookie保存在客戶端,存在篡改或劫持的風險。故cookie不能存儲重要信息,通常只保存憑證,服務端會根據cookie從數據庫或session中查找具體信息。服務器

關於cookie更詳細的介紹能夠看維基百科 ➡️ HTTP cookiecookie

session

1. session是什麼session

session本質是一段保存在服務端內存中的代碼片斷,session的實現通常是基於cookie的。cookie記錄憑證,session記錄具體數據。架構

2. session存在問題分佈式

  • session會佔用內存,開銷大。傳統的session保存在內存裏,每當用戶登陸時,在session作一次記錄。隨着認證用戶的增多,服務端的開銷會明顯增大。
  • session橫向擴展差。頁面的請求不必定是同一臺服務器,若是請求打到不一樣服務器,那麼服務器之間須要共享session。此時須要作session的持久化,若是持久化失敗就出現認證失敗。

jwt

jwt全稱json web token,是目前最流行的跨域身份驗證解決方案。

1. 解決的問題

傳統的session不支持分佈式架構,沒法支持橫向擴展,只能經過數據庫來保存會話數據實現共享。若是持久層失敗會出現認證失敗。回到問題的本質,是由於服務端須要記錄客戶端對應的信息,來鑑別客戶端狀態。

而使用jwt,服務端不須要記錄客戶端對應的信息。服務端經過對token上攜帶的信息進行處理可以確認這個token是不是有效。服務器變爲無狀態,使其更容易擴展。

2. token的組成

jwt生成的token由3部分組成:頭、內容、簽名,經過符號`.`鏈接。

1. Header 頭部

  • 聲明類型,這裏是JWT
  • 聲明加密的算法,這裏是HS256

Header的示例:

{
  'typ': 'JWT',
  'alg': 'HS256'
}複製代碼

2. Payload 內容:存放有效信息,例如過時時間,面向用戶等

Payload的示例:

{
  "exp": "1234567890",
  "name": "John Doe"
}複製代碼

3. Signature 簽名

Signature 由下面兩步獲得

  1. 將base64加密後的Header和base64加密後的Payload使用.鏈接組成的字符串

  2. 將字符串進行Header中聲明的加密方式進行加鹽secret組合加密

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

3. 鑑權原理

① 客戶端發送/login請求到服務端A,服務端A校驗登陸經過後生成token。

② 服務端A將token返回給客戶端。

③ 客戶端發送/list請求到服務端B,同時在請求頭裏攜帶了token。服務端將token拆解成header+payload+signature三部分,再次將header.payload進行加密,獲得新的signature。若是新的signature和舊的signature相等則表示當前客戶端是登陸過的狀態。

④ 服務端B校驗經過,返回數據給客戶端。

4. 經常使用的jwt庫有

jwt-simple

jsonwebtoken

總結

讀完這篇文章,但願你能對cookie、session和jwt有必定的瞭解。

傳統的cookie+session的鑑權形式有必定的侷限性,表如今:

1. session佔用服務器內存

2. session的橫向擴展性很差,須要數據持久化。數據持久化若是失敗影響鑑權。

使用jwt能讓服務器變成無狀態的,即服務器不需保存當前請求的會話信息。實現原理是:

  • 在初次請求時,服務端生成一個token返回給客戶端;
  • 客戶端再次請求時攜帶token,服務端將token拆解成header+payload+signature三部分,將header.payload進行加密,獲得新的signature。若是新的signature和舊的signature相等則表示經過,當前客戶端是登陸過的狀態。
相關文章
相關標籤/搜索