詳解 Session 和 Cookie


前提

51 也有個文章跟我一樣,是我自己投的稿哈

 

為什么要用Session和Cookie?

簡單一句話,因為 Session 和 Cookie 可以記錄用戶狀態信息

嘶..這到底啥意思呢?

 

背景一:動態網頁的出現

什么是靜態網頁

  • 含義:一個網頁的內容是 HTML 代碼編寫的,文字、圖片等內容均可通過HTML代碼指定了
  • 優勢:加載速度快,編寫簡單
  • 劣勢:可維護性差,擴展性差,不能根據URL顯示不同的內容;例如:在 URL 傳入一個name參數想在網頁上顯示,靜態網頁是無法做到的
  • 總結:弊大於利

 

動態網頁的誕生

  • 動態網頁可以動態解析 URL 中參數的變化,關聯數據庫並動態呈現不同的頁面內容,非常靈活多變
  • 現在遇到的大多數網站都是動態網站,不再是一個簡單的 HTML 頁面,可能由 JSP、PHP、Python 等語言編寫的,功能比靜態網頁強大和豐富太多

場景:一個需要登錄的動態網站,在登錄后需要保持登錄狀態,以便后續訪問網站其他網頁;那么我們要通過什么來保存這個登錄態呢?

 

背景二:HTTP是無狀態協議

HTTP無狀態是指?

HTTP協議對事務處理是沒有記憶能力,也就是說服務器不知道客戶端是什么狀態

 

這是什么意思呢?

  • 當我們向服務器發送請求后,服務器解析處理請求,然后返回響應,服務器負責完成這個過程(也是一個事務)
  • 而這個過程是獨立的,服務器不會記錄前后狀態的變化,也就是缺少狀態記錄

 

無狀態導致的后果?

  • 意味着后續發出的請求需要處理前面請求的響應,則必須重傳
  • 這也導致需要額外傳遞一些前面的重復請求,才能獲取后續響應
  • 但為了保持前后狀態,我們也不能將前面的請求全部重傳一次,這太浪費資源了
  • 就好像如果一個網站每次發出一個請求前都要先發出一次登錄請求,這無疑大大增加了資源浪費程度

 

舉栗子:百度

網站常常需要記錄訪問者的一些基本信息,例如:用戶是否登錄、用戶登錄名稱、密碼、用戶在 Web 站點購物的方式或用戶訪問該站點的次數

舉個例子,用戶在沒有登錄 baidu 時,此時用戶的身份是游客,baidu 首頁的界面如下圖所示:

 

當用戶登錄 baidu 頁面后,此時用戶的身份是已登錄用戶,可以看到頁面的右上角顯示了用戶的名稱,如下圖所示

  • 可以看出,baidu 服務端能夠辨別用戶的身份,根據用戶是否登錄顯示不同的內容
  • 如果用戶的身份是游客,則顯示登錄
  • 如果是已登錄用戶,則顯示用戶的名稱

 

Seesion和Cookie的誕生

上圖可以看出,Session 和 Cookie 在一個網站中各自發揮的作用

 

使用 Cookie 辨別用戶的身份

  • 網站為了辨別用戶身份、進行會話跟蹤需要把一些數據(例如:登錄狀態、用戶名稱)儲存在用戶本地終端上,這些數據被稱為 Cookie
  • 以登錄 baidu 為例子,用戶在沒有登錄 baidu 時,訪問的網頁 URL 是 https://www.baidu.com
  • 在登錄 baidu 后,訪問的網頁 URL 仍然是 https://www.baidu.com
  • 訪問的頁面 URL 相同,但是這兩次訪問呈現的結果不相同,登錄前沒有顯示用戶名,登錄后顯示了用戶名  

 

那服務端是怎么區分兩個請求呢?

  1. 用戶登錄 baidu
  2. baidu 服務端會生成一個用戶 ID
  3. baidu 服務端將這個用戶 ID 發送給瀏覽器
  4. 瀏覽器收到這個用戶 ID 后,會將這個用戶 ID 保存在用戶本地終端
  5. 瀏覽器再次訪問 baidu 站點時,瀏覽器會將保存在本地的用戶 ID 發給 baidu 服務端
  6. 服務端收到瀏覽器發送的用戶 ID 后,就知道此次請求來自於一個已登錄的用戶

以上交互過程中,保存在客戶端的用戶ID 就是 Cookie 

 

實際場景

  1. 當我們登錄之后,服務端就會創建一個屬於當前用戶的 Session,里面保存的就是當前用戶的信息;
  2. 然后瀏覽器會根據服務器的響應頭中 Set-Cookie 字段生成相關 Cookie,相當於一個用戶憑證
  3. 只需要在下次請求時攜帶這些 Cookie,服務器就能通過 Cookie 來判斷用戶是否是登錄狀態,然后返回對應的響應

不好理解?繼續往下看!

 

生動形象理解Cookie和Session的關系

  1. Session 是保存在服務器端,Cookie 是保存在客戶端
  2. 每次用戶訪問網站的時候,相當於去串門
  3. 用戶帶着 cookie 去服務器家,當當當敲門
  4. 服務器問是誰啊
  5. 用戶:是我(cookie)啊
  6. 服務器:讓我來確認一下(session確認)
  7. 服務器確認完畢后,放用戶進門

 

實際網站登錄請求的響應頭

  1. 這是一個網站登錄之后返回的響應頭,可以看到服務器要求瀏覽器設置的 Cookies 有好幾個;這就是 Cookies 的來源,而 token 一般會作為用戶的唯一憑證【登錄成功,響應頭set-cookies,瀏覽器設置Cookies】
  2. 當瀏覽器下一次再請求該網站時,瀏覽器會把這些Cookies放到請求頭一起提交到服務器;而Cookies攜帶了SessionID信息(x-token)【再次請求,帶上 cookies,包含 SessionID】
  3. 服務器通過 SessionID 即可找到對應的用戶 Session 信息,然后判斷該用戶的登錄狀態【服務器根據 SessionID 獲取用戶信息】
  4. 如果 Session 中某些設置登錄狀態的變量是有效期內的,證明用戶處於登錄狀態【Session 有效,用戶已登錄】
  5. 此時服務器就會返回需要登錄之后才可以查看的網頁內容,瀏覽器再進行解析便可以看到了【返回請求響應內容】
  6. 當 Cookie 無效或者 Session 已過期后,我們再訪問網站就需要重新登錄了【Cookie 無效,Session 過期,需要再次登錄】

 

使用 Cookie、Session 最簡單的流程圖

 

Session和Cookie在登錄功能上的協同關系

 

Session

  • 是在服務端保存的一個數據結構
  • 用來存儲用戶的信息(比如登錄狀態、用戶名稱)
  • Session 數據可以保存在內存(比如 Redis)、文件或數據庫中
  • Session 有一個唯一標識 SessionID,會對應一個用戶
  • 在服務端通過 SessionID 會找到特定的一個用戶數據

 

小栗子

  • 假設有 2 個用戶:用戶 A 和用戶 B;
  • 在服務端存在 2 個 Session,用於存儲用戶 A 和用戶 B 的數據

在服務端通過 SessionID 查找 Session 的過程如下

  1. 每一個 Session 有一個唯一標識,用戶A 的 SessionID 為0,用戶B 的 SessionID 為1
  2. 用戶訪問網站時,會把自己的 SessionID 作為 Cookie 發送給服務端
  3. 服務端根據請求中的 SessionID 來查找對應的 Session

 

實際場景

  • 在Web中,Session對象用來存儲特定用戶 Session 所需的屬性和配置信息,這樣用戶在應用程序的Web頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶 Session 中存在下去
  • 當用戶請求網頁時,該用戶還沒有 Session,則Web服務器將自動創建一個 Session 對象
  • 當 Session 過期或被放棄后,服務器將終止該 Session

 

Cookie

某些網站為了辨別用戶身份,進行 Session 跟蹤而存儲在用戶本地終端上的數據

 

會話Cookie和持久Cookie

會話Cookie

可以將打開瀏覽器-關閉瀏覽器理解成一個會話,會話Cookie的有效期僅在瀏覽器打開期間;而會話Cookie是存在瀏覽器內存里的

實際場景:涉及錢,涉及利益、機密內容的網站一般都是會話Cookie,如企業郵箱等

 

持久Cookie

持久Cookie是存在客戶端本地硬盤中,不受瀏覽器關閉影響,下次再次訪問該網站時還能繼續使用,用於長久保持用戶登錄狀態

實際場景:可以勾選【自動登錄】、【30天內自動登錄】的網站用的就是持久Cookie

 

持久Cookie發出請求時,客戶端與服務器之間的時序圖

 

瀏覽器中看Cookie

  • Name:Cookie 的名稱。Cookie 一旦創建,名稱便不可更改
  • Value:Cookie 的值。如果值為 Unicode 字符,需要為字符編碼。如果值為二進制數據,則需要使用 BASE64 編碼。
  • Domain:Cookie注入的域名,如.baidu.com下的Cookie,只要Host以.baidu.com結尾的域名都能訪問該Cookie
  • Path:允許使用該Cookie的路徑,一般都為 / 
  • Expires/Max-Age:Cookie失效時間,若沒有指定失效時間則默認當瀏覽器關閉時Cookie失效
  • Size:Cookie大小
  • HttpOnly:若True,則不允許腳本來訪問該Cookie(如:JS)
  • Secure:Cookie是否僅被使用安全協議傳輸,默認為False

 

敲重點的知識點

“只要關閉瀏覽器,Session 就消失了” —— 錯!

實際場景:去健身房辦理的會員卡,除非你自己要求銷卡,不然店家不會隨意銷掉你的卡

所以,對於 Session 也是一樣的,登錄的時候服務器幫你生成了一個 Session,是不會輕易刪除你的 Session,除非你自己提出要刪除 或 Session有效期過了;而一般我們會通過【退出】來刪除觸發服務器刪除 Session

 

當我們關閉瀏覽器時,瀏覽器是不會通知服務器說它要關閉,所以服務器根本不知道瀏覽器已關閉,造成這樣的誤解全都是因為:

  1. 一般情況下,網站都會用 Cookie 來保存 SessionID 信息的
  2. 當你的 Cookie 是會話 Cookie 時,關閉瀏覽器 Cookie 就會消失
  3. 再次打開網站也找不回之前的那個 Cookie 對應的 SessionID
  4. 所以無法通過原來的 SessionID 在服務器查找對應用戶的登錄狀態,只能重新登錄生成新的 Cookie 來記錄新的 SessionID

 

如何解決?

就是將 Cookie 設置為持久 Cookie,當你關閉瀏覽器再打開網站時,還是能從本地讀取到 Cookie,從而獲取到原來的 SessionID,以此來保持登錄狀態

 

另外

而恰恰因為關閉瀏覽器並不會讓服務器主動刪除 Session,為了避免服務器的資源浪費,一般服務器都會為每個 Session 設置一個失效時間,當 Session 的時間超過失效時間時,服務器會自動刪除 Session

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM