Session 和 Cookie 的概念
現在正式進入第四部分學習,作為開頭部分,我們首先要介紹下 Web 框架中常用到的 Cookie 和 Session 的概念。在了解了這些基礎知識后,我們就可以學習 Django 中是如何使用 Cookie 和 Session 幫我們完成一些簡單的必要功能。話不多說,現在就開始吧!
1. 為什么需要Cookie和Session?
在 Web 程序中,對會話的跟蹤是很一件非常重要的事情。通常,一個用戶的所有請求操作都應該屬于同一個會話,而另一個用戶的所有請求操作則應該屬于另一個會話,二者不能互不干擾。然而大部分的 Web 應用程序都是使用HTTP 協議傳輸數據的。HTTP協議是無狀態的協議。一旦數據交換完畢,客戶端與服務器端的連接就會關閉,再次交換數據需要建立新的連接。這就意味著服務器無法從連接上跟蹤會話。如果 Web 服務上沒有這種的會話追蹤功能,那么大部分網站都會陷入一片混亂。特別是對于電商網站而言,如果我添加一次購物車就需要登錄一次確認身份,那對于用戶體驗而言是糟糕透的。會話(Session)跟蹤是 Web 程序中常用的技術,用來跟蹤用戶的整個會話。常用的會話跟蹤技術是Cookie與Session。Cookie通過在客戶端記錄信息確定用戶身份,Session通過在服務器端記錄信息確定用戶身份。正是有了 Cookie 和 Session 這樣的會話跟蹤技術,彌補了 HTTP 協議無狀態的不足,才使得我們可以無差別的訪問網站,即只需要一次登錄,后續所有的操作通過 Cookie 或者 Session 便能自動識別為該用戶,并維持在一個會話中。
2 Cookie
2.1 什么是Cookie?
前面已經介紹了,Cookie 是一種會話跟蹤技術,且將用戶信息記錄在客戶端,通常是我們自己電腦上的某個位置,這個位置是固定的,和使用的瀏覽器有關。目前Cookie已經成為標準,所有的主流瀏覽器如 IE、Netscape、Firefox、Opera 以及 Chrome 等都是支持 Cookie 的。
Cookie 實際上是一小段的文本信息??蛻舳苏埱蠓掌鳎绻掌餍枰涗浽撚脩魻顟B,就使用response向客戶端瀏覽器頒發一個 Cookie??蛻舳藶g覽器會把 Cookie 保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該 Cookie 一同提交給服務器。服務器檢查該 Cookie,以此來辨認用戶狀態。服務器還可以根據需要修改 Cookie 的內容。
現在我們訪問下慕課網,然后進行登錄,登錄之后我們所有在慕課網中的操作都會帶上這個 Cookie 去請求后端服務,這樣后端服務通過 Cookie 就能識別請求的用戶。參考下面兩個圖,第二個是 Cookie 的真實位置,它是放到請求頭部中的,具體內容是用逗號分隔的 key=value
形式。
此外, 我們在前端調試工具頁面中選擇 Console Tab 頁面,輸入一行 js 代碼就能拿到對方網站發給我們的 cookie值:
2.2 Cookie的特點
Cookie 有如下特點:
不可跨域名性:
這個是 Cookie 非常重要的一個特點,域名限制。表示 A 網站頒發的 Cookie 在用戶訪問 B 網站時并不會被提交到 B 網站上去,這些都是由 Cookie 規范確定。此外,W3C 標準還禁止了 JavaScript 讀寫任何不屬于自己網站的 Cookie;
時間限制:
Cookie 同樣有著自己的生命周期,其 maxAge 值決定著 Cookie 的有效期,單位為秒。如果maxAge 屬性為正,則表示該 Cookie 會在 maxAge 秒之后自動失效。瀏覽器會將 maxAge 為正數的 Cookie持久化,即寫到對應的 Cookie 文件中。無論客戶關閉了瀏覽器還是電腦,只要還在 maxAge 秒之前,登錄網站時該 Cookie 仍然有效;如果 maxAge 為負數,則表示該 Cookie 僅在本瀏覽器窗口以及本窗口打開的子窗口內有效,關閉窗口后該 Cookie 即失效。maxAge 為負數的 Cookie,為臨時性 Cookie,不會被持久化,不會被寫到 Cookie 文件中。Cookie 信息保存在瀏覽器內存中,因此關閉瀏覽器該 Cookie 就消失了。Cookie 默認的 maxAge 值為–1;而如果 maxAge 為0,則表示刪除該 Cookie。Cookie 機制沒有提供刪除 Cookie 的方法,因此通過設置該 Cookie 即時失效實現刪除 Cookie 的效果。失效的 Cookie 會被瀏覽器從 Cookie 文件或者內存中刪除;
- 空間限制:Cookie 只能存儲4-10KB;
- 數量限制:一般而言,每個域下最多不能超過50個 Cookie
- 存儲數據類型限制:Cookie只能存儲字符串
從上面這些特點,我們也能發現使用 Cookie 的一些缺點。使用 Cookie 最大的問題就是安全性,因為 Cookie 是保存在客戶端的,且每次發送 HTTP 請求都會將 Cookie 帶過去。這些都導致 Cookie 很容易泄露出去,如果一旦 Cookie 泄露,且 Cookie 中設置的時間較長,那么很可能攻擊者拿著這個 Cookie 就能冒充受害者的身份去做一些事情,最后留下的記錄都是受害者的。然而接下來的 Session 在某種程度上避免了這一類的問題。
3. Session
3.1 什么是Session?
Session 是另一種記錄客戶狀態的機制,不同于 Cookie 保存在客戶端瀏覽器中,Session 數據時保存在服務器上。瀏覽器訪問服務器的時,服務器會把客戶端信息以某種形式記錄在服務器上,這些數據就是 Session??蛻舳藶g覽器再次訪問時只需要從該 Session 中查找該客戶的狀態就可以了。
Cookie 機制是通過檢查客戶身上的“通行證”來確定客戶身份,Session 機制是通過檢查服務器上的“客戶明細表”來確認客戶身份。Session 相當于程序在服務器上建立的一份客戶檔案,客戶來訪的時候只需要查詢客戶檔案表就可以了。
當多個客戶端執行程序時,服務器會保存多個客戶端的 Session。獲取 Session 的時候也不需要聲明獲取誰的Session。Session 機制決定了當前客戶只會獲取到自己的 Session,而不會獲取到別人的 Session。各客戶的Session 也彼此獨立,互不可見。
Session 的使用雖然比 Cookie 方便許多,但是過多的 Session 存儲在服務器內存中,會對服務器造成壓力。
3.2 Session的生命周期
這里我們談談 Session 的生命周期,和 Cookie 有所不同。首先 Session 保存在服務器端,為了獲得更高的存取速度,服務器一般把Session放在內存里。Session 會在用戶第一次訪問服務器的時候自動創建。Session 生成后,只要用戶繼續訪問,服務器就會更新 Session 的最后訪問時間,并維護該 Session。用戶每訪問服務器一次,無論是否讀寫 Session,服務器都認為該用戶的 Session “活躍”了一次。
由于會有越來越多的用戶訪問服務器,因此 Session 也會越來越多。為防止內存溢出,服務器會把長時間內沒有活躍的 Session 從內存刪除。這個時間就是 Session 的超時時間。如果超過了超時時間沒訪問過服務器,Session 就自動失效了。
3.3 Cookie 和 Session 之間的區別
介紹完了 Cookie 和 Session 之后,我們現在來看看二者的區別,當然最大的區別前面已經反復強調過了:
- Cookie 數據存放在客戶的瀏覽器上,Session 數據放在服務器上;
- 上面的區別也導致了 Cookie 和 Session 之間安全性的差別。Cookie 數據保存在用戶端,數據容易被竊取,不太安全。雖然對 Cookie 中的敏感信息加密可以暫時規避安全風險,但即使加密數據被泄露了總歸是不好的;Session 數據存儲在服務器,可以有效規避信息泄露問題;
- Cookie 和 Session 之間生命周期不同,具體可以看前面兩個的介紹;
- 單個 Cookie 保存的數據不能超過4K,很多瀏覽器都會限制一個站點最多保存20個 Cookie,且只能保存字符串內容;對于 Session 則沒多少限制,Session 可以保存復雜的數據類型,而且數量沒有限制,主要是訪問用戶太多后,容易造成服務器內存溢出。
4. 小結
本小節中我們詳細介紹了 Cookie 和 Session 中的一些基本概念以及各自的優缺點。在了解了這些基礎知識后,我們就可以在 Django 中操作 Cookie 和 Session 了。