1. 程式人生 > 其它 >Django Session 和 Cookie

Django Session 和 Cookie

前言

http:無狀態請求(客戶端發起的無數請求,服務端並不知道是否來自同一個客戶端),所以引入session來做相應響應和許可權處理。

cookie和session區別與聯絡

cookie儲存在客戶端
session儲存在服務端

由於http的無狀態性,為了使某個域名下的所有網頁能夠共享某些資料,session和cookie出現了。客戶端訪問伺服器的流程如下:

  • 首先,客戶端會發送一個http請求到伺服器端。

  • 伺服器端接受客戶端請求後,建立一個session,併發送一個http響應到客戶端,這個響應頭,其中就包含Set-Cookie頭部。該頭部包含了sessionId。Set-Cookie格式如下,
    Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

  • 在客戶端發起的第二次請求,假如伺服器給了Set-Cookie,瀏覽器會自動在請求頭中新增cookie

  • 伺服器接收請求,分解cookie,驗證資訊,核對成功後返回response給客戶端

如圖,cookie和session共同完成了一次瀏覽器會話的過程:

Django Session 和 Cookie的約定

其中Set-Cookie可以對session的有效期進行設定,圖中的Max-Age=300就是在服務端做了有效期為5分鐘的設定。

注意

  • cookie只是實現session的其中一種方案。雖然是最常用的,但並不是唯一的方法。禁用cookie後還有其他方法儲存,比如放在url中
  • 用session只需要在客戶端儲存一個id,實際上大量資料都是儲存在服務端。如果全部用cookie,資料量大的時候客戶端是沒有那麼多空間的。
  • 如果只用cookie不用session,那麼賬戶資訊全部儲存在客戶端,一旦被劫持,全部資訊都會洩露。並且客戶端資料量變大,網路傳輸的資料量也會變大

Token方法

  • token 也稱作令牌,由uid+time+sign[+固定引數]
  • token 的認證方式類似於臨時的證書籤名, 並且是一種服務端無狀態的認證方式, 非常適合於 REST API 的場景. 所謂無狀態就是服務端並不會儲存身份認證相關的資料。

組成

uid: 使用者唯一身份標識
time: 當前時間的時間戳
sign: 簽名, 使用 hash/encrypt 壓縮成定長的十六進位制字串,以防止第三方惡意拼接
固定引數(可選): 將一些常用的固定引數加入到 token 中是為了避免重複查庫

存放

token在客戶端一般存放於localStorage,cookie,或sessionStorage中。在伺服器一般存於資料庫中

token認證流程

token 的認證流程與cookie很相似

  • 使用者登入,成功後伺服器返回Token給客戶端。
  • 客戶端收到資料後儲存在客戶端
  • 客戶端再次訪問伺服器,將token放入headers中
  • 伺服器端採用filter過濾器校驗。校驗成功則返回請求資料,校驗失敗則返回錯誤碼

分散式情況下的session和token

  • session是有狀態的,一般存於伺服器記憶體或硬碟中,當伺服器採用分散式或叢集時,session就會面對負載均衡問題。
    負載均衡多伺服器的情況,不好確認當前使用者是否登入,因為多伺服器不共享session。這個問題也可以將session存在一個伺服器中來解決,但是就不能完全達到負載均衡的效果。當今的幾種解決session負載均衡的方法(Nginx IP hash)。https://blog.51cto.com/zhibeiwang/1965018

  • token是無狀態的,token字串裡就儲存了所有的使用者資訊;
    客戶端登陸傳遞資訊給服務端,服務端收到後把使用者資訊加密(token)傳給客戶端,客戶端將token存放於localStroage等容器中。客戶端每次訪問都傳遞token,服務端解密token,就知道這個使用者是誰了。通過cpu加解密,服務端就不需要儲存session佔用儲存空間,就很好的解決負載均衡多伺服器的問題了。這個方法叫做JWT(Json Web Token)

  • 基於token的鑑權機制類似於http協議也是無狀態的,它不需要在服務端去保留使用者的認證資訊或者會話資訊。這就意味著基於token認證機制的應用不需要去考慮使用者在哪一臺伺服器登入了,這就為應用的擴充套件提供了便利。

  • 這個token必須要在每次請求時傳遞給服務端,它應該儲存在請求頭裡, 另外,服務端要支援CORS(跨來源資源共享)策略,一般我們在服務端這麼做就可以了Access-Control-Allow-Origin: *。

總結

  • session儲存於伺服器,key-value列表,擁有一個唯一識別符號sessionId,通常存放於cookie中。伺服器收到cookie後解析出sessionId,再去session列表中查詢,才能找到相應session。
  • cookie裝有sessionId(狀態協議),儲存在客戶端,瀏覽器通常會自動新增。
  • token是一個令牌,客戶端和服務端無狀態連線(http無狀態協議),使用者資訊都被加密到token中,伺服器收到token後解密就可知道是哪個使用者。後端要寫加密/解密方法。
  • jwt只是一個跨域認證的方案