天天看點

Cookie和Session 你真的懂嗎?Cookie 和 Session 基本概念

Cookie 和 Session 基本概念

什麼是無狀态

無狀态是指Web浏覽器與Web伺服器之間不需要建立持久的連接配接,這意味着當一個用戶端向伺服器端送出請求,然後Web伺服器傳回響應(Response),連接配接就被關閉了,在伺服器端不保留連接配接的有關資訊。也就是說,HTTP請求隻能由用戶端發起,而伺服器不能主動向用戶端發送資料。

Cookie

Cookie 是一些資料, 存儲于你電腦上的文本檔案中 —菜鳥教程

一種http會話機制,為了解決HTTP協定本身是無狀态的( “如何記錄用戶端的使用者資訊”😃, 是以,在第一次向伺服器發送請求沒有cookie(假設是沒有任何操作記錄), 伺服器通過在響應封包的Set-Cookie設定對應的cookie值,以便用戶端下次發送請求帶上cookie,伺服器通過識别cookie實作繼續會話(互動)

Cookie 是存儲在用戶端

這一點很容易了解,在浏覽器裡,cookie相當于緩存一樣,在前台可以document.cookie檢視cookie,在開發者工具的application可以看到浏覽器目前域名下的cookie完備的資訊

Cookie 後端可操作 Set-Cookie

  1. Cookie既然是會話機制,那麼和伺服器交流肯定要傳給後端,是以每次再向後端接口請求的請求封包是會帶上Cookie告訴後端資訊,以便維持會話狀态。
  2. Cookie在通路伺服器時,伺服器可能會在響應消息中增加Set-Cookie字段,将資訊以|Cookie形式發送給浏覽器,一旦浏覽器接受到伺服器發送的Cookie消息,那麼會将其儲存到浏覽器的緩沖區,以便下次會話交換資訊。
  3. 看一張圖 (該圖來源于黑馬教程的一本書,應該是php的,但是已經忘記了)
    Cookie和Session 你真的懂嗎?Cookie 和 Session 基本概念

Cookie的幾種登入方式

  1. 把登入資訊如賬号、密碼等儲存在Cookie中,并控制Cookie的有效期,下次通路時再驗證Cookie中的登入資訊即可。這是一種比較危險的選擇,一般不把密碼等重要資訊儲存到Cookie中
  2. 一種方案是把密碼加密後儲存到Cookie中,下次通路時解密并與資料庫比較(可能僞造cookie登入),還可以把登入的時間戳儲存到Cookie與資料庫中,到時隻驗證使用者名與登入時間戳就可以了。
  3. 隻在登入時查詢一次資料庫,以後通路驗證登入資訊時不再查詢資料庫。自定義密鑰Key,

    把賬号和Key按照一定的規則加密後,連同賬号一塊儲存到Cookie中。下次通路時隻需要判斷賬号的加密規則是否正确即可(通過傳來的user類字段和Key再次加密比對Cookie)。(可能僞造cookie登入)

Session

Session利用上了Cookie
  1. Session是一種伺服器端技術,它的生命周期從使用者通路頁面開始,直到與網站的連接配接結束。

    當服務端調用Session服務(在一些書上說啟動Session,而事實上隻有當代碼級别的調用Session才會啟用Session),web伺服器在運作期間為通路該伺服器的浏覽器建立一個獨享的Session檔案。在建立Session檔案時,每個Session都具有一個唯一的會話ID,用于辨別不同的ID(一般是一段長串),且會話ID分别存儲在服務端和用戶端(Set-Cookie寫回Cookie 這一系列從調用session時自動完成,也許就是是以稱為伺服器端技術把)。

  2. 看下圖以PHP為例(該圖來源網絡)
    Cookie和Session 你真的懂嗎?Cookie 和 Session 基本概念
  3. 當浏覽器第二次通路伺服器時,Session服務自動根據SessionID(請求時會自動的帶上Cookie這是關鍵)識别使用者,讀取對應的session檔案,此時程式操作的session時獨立的(每個浏覽器通路,伺服器開辟一個獨立的程序/線程/異步處理)

    ,使用者代碼層次擷取的session就是目前讀取的session檔案,至此會話連接配接成功。是以,其實對于用戶端來說,session是透明的(透明的就是看不見的意思,也不需要前端的同學關注set-cookie寫回和攜帶cookie去請求,都是自動完成,當然一部分是互動的機制實作)。

  4. 看個NodeJs(這是基于koa的EggJs架構)的例子就知道了:
// 存儲設定session
const {ctx} = this    //session自動綁定到ctx上,是以擷取
ctx.session.user = sqlUser.username; //session 儲存username 到session ,
/*
  注意,隻有寫到這個代碼層次,才開啟了session服務流程 (當然如果你要用session要進行一些配置),伺服器已經生成sessionId,儲存記錄username,最後寫入
檔案(一般是一個用戶端對應一個session檔案,以便提高通路速度)
*/

//當用戶端再次通路伺服器資源時
const username = ctx.session.user //注意,用戶端通路是,是帶有Cookie的,伺服器自動處理識别"EGG_KEY"(這是這個架構存儲用戶端cookie的sessionId的鍵)并通路對應的sission檔案,至此
//ctx.session已經存在資料供開發成員使用
           
你可以注意到,session依賴于cookie的識别,設定,攜帶。一旦用戶端禁止Cookie,那這種方式将失效
  1. 如果用戶端禁止Cookie,那伺服器應該把SessionId手動傳回給用戶端,用戶端請求時,再請求體或者參數攜帶SessionId,伺服器再驗證SessionId以讀取對應的檔案,擷取目前用戶端的對應session資料。
nodejs的session(各種版本的中間件)普遍沒有暴露擷取sessionid的方法,其它後端語言怎麼樣我不是特别清楚,如果懂求nodejs怎麼擷取大佬為萌新解答,謝謝哦。

繼續閱讀