
淘寶、天貓、京東等電商網(wǎng)站的出現(xiàn),讓我們足不出戶就能購物。在這些網(wǎng)站中,都有一個(gè)“購物車”的功能。當(dāng)我們在不同商品頁面將商品加入購物車,然后關(guān)閉瀏覽器。等下次瀏覽該網(wǎng)站時(shí),我們會依然發(fā)現(xiàn)購物車的商品還在。這是怎么實(shí)現(xiàn)的了?類似這種場景,一般都是采用 Cookie + Session 方式來實(shí)現(xiàn)。
1 Cookie 機(jī)制
HTTP 協(xié)議是無狀態(tài)的。所以服務(wù)器無法根據(jù) HTTP 協(xié)議來辨別多個(gè) HTTP 請求來自哪個(gè)用戶。在實(shí)際場景中,服務(wù)器經(jīng)常需要追蹤客戶端的狀態(tài)。為了解決這個(gè)問題, Cookie 技術(shù)應(yīng)運(yùn)而生。
cookie 一開始是服務(wù)器產(chǎn)生的一段隨機(jī)字符串。它的主要內(nèi)容包括:名字,值,過期時(shí)間,路徑與域等信息。然后服務(wù)器將其發(fā)送給客戶端。在后續(xù)的請求中,cookie 會附在請求資源的 HTTP 請求頭上,發(fā)送給服務(wù)器。
2 Session 機(jī)制
如果不涉及用戶登錄等敏感信息時(shí),Cookie 能夠滿足大部分的場景需求。而客戶端(如瀏覽器)會將 Cookie 是保存在硬盤中。如果用戶登錄敏感信息保存到 cookie 中,會存在安全性問題。因?yàn)楫?dāng) HTTP 請求被黑客攔截,然后劫持 cookie 信息。黑客就可以憑借該 cookie 登錄對應(yīng)的網(wǎng)站。
Session 的出現(xiàn)很好地解決的這個(gè)問題。Session 機(jī)制是一個(gè)服務(wù)器端的機(jī)制。它會將信息保存服務(wù)器端,跟客戶端通信只需要一個(gè)隨機(jī)的字符串 session_id。如果客戶端沒有禁止 Cookie 功能,session_id 通常是保存在 Cookie中 的。如果 Cookie 被禁用,它則可能通過為 url 加上query string 來添加 session_id。
3 在 Django 中的應(yīng)用
Django 為我們提供了一個(gè)通用的 Session 框架。使用 Django 2.X 版本創(chuàng)建新項(xiàng)目的時(shí),Django 默認(rèn)會幫我們啟用該功能。
Django 默認(rèn) Session 數(shù)據(jù)保存到數(shù)據(jù)庫中,可以在 settings.py 中看到配置信息項(xiàng)目。
INSTALLED_APPS = [
# 啟用 sessions 應(yīng)用
'django.contrib.sessions',
]
MIDDLEWARE = [
# 啟用 Session 中間層
'django.contrib.sessions.middleware.SessionMiddleware',
]
然后我們在將自帶組件的模型同步到數(shù)據(jù)庫中。如果你還不熟悉這塊內(nèi)容,可以閱讀《Django 學(xué)習(xí)筆記之模型(上)》這篇文章。我們之后會看到數(shù)據(jù)庫中有個(gè) django_session 表:

除了上述的基于數(shù)據(jù)庫的會話,Django 還提供另外三種方法:
1)保存到緩存中
如果你的場景需要快速存儲會話,可以選擇該方案。使用之前,需要配置下 Django 的緩存框架。在 settings.py 中增加 SESSION_ENGINE 配置。
這其中也是有兩種保存數(shù)據(jù)的方案,具體配置如下:
- 方案一
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
這種配置方案 Django 只是簡單保存會話。同時(shí),這種方案持久性不好。因?yàn)楫?dāng)緩存數(shù)據(jù)存滿時(shí)將清除部分?jǐn)?shù)據(jù),或者遇到緩存服務(wù)器重啟時(shí)數(shù)據(jù)將丟失。
- 方案二
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
這種方案既保證快速存儲會話數(shù)據(jù),又保證數(shù)據(jù)持久性。因?yàn)樵撌褂梅桨福?Session 在保存到緩存的同時(shí)還會被保存到數(shù)據(jù)庫中,當(dāng) Django 在緩存中找不到Session 時(shí),會從數(shù)據(jù)庫中找到。因此,這種方案的性能開銷會比方案一大。
如果我們在工程中同時(shí)配置了數(shù)據(jù)庫會話和緩存會話,Django 默認(rèn)優(yōu)秀選擇緩存會話。
2)保存到文件中
這種方案是保存數(shù)據(jù)到本地磁盤中。因?yàn)榇疟P的 I/O 瓶頸問題,導(dǎo)致這種方案存儲數(shù)據(jù)效率不是很高。如果要使用這種方案,在 settings.py 中增加 SESSION_ENGINE 配置。具體配置如下:
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
# 可選配置
SESSION_FILE_PATH = '/monkey/www/'
SESSION_FILE_PATH 默認(rèn)使用 tempfile.gettempdir() 方法的返回值,就像 /tmp目錄。如果你想更新文件的保存路徑,可以手動指定。另外需確保你的文件存儲目錄,以及 Web 服務(wù)器對該目錄具有讀寫權(quán)限。
3)保存到 cookie 中
這種方案將數(shù)據(jù)保存到 cookie 中。這種方案適用于對數(shù)據(jù)保密性不嚴(yán)格的場景。如果要使用這種方案,在 settings.py 中增加 SESSION_ENGINE 配置。具體配置如下:
SESSION_ENGINE = 'jango.contrib.sessions.backends.signed_cookies'
# 建議配置,阻止 javascript 對會話數(shù)據(jù)的訪問,提高安全性。
SESSION_COOKIE_HTTPONLY= True
往前 Django 學(xué)習(xí)筆記文章
Django 學(xué)習(xí)筆記之環(huán)境搭建
Django 學(xué)習(xí)筆記之初始
Django 學(xué)習(xí)筆記之視圖與URL配置
Django 學(xué)習(xí)筆記之模板
Django 學(xué)習(xí)筆記之模型(上)
Django 學(xué)習(xí)筆記之模型(下)
Django 學(xué)習(xí)筆記之后臺管理
Django 學(xué)習(xí)筆記之模型表單
Django 學(xué)習(xí)筆記之使用舊數(shù)據(jù)庫
Django 實(shí)戰(zhàn)1:搭建屬于自己社工查詢系統(tǒng)(上)
Django 實(shí)戰(zhàn)1:搭建屬于自己社工查詢系統(tǒng)(下)
Django 學(xué)習(xí)筆記之模型高級用法(上)
Django 學(xué)習(xí)筆記之模型高級用法(下)
Django 實(shí)現(xiàn)分頁功能
本文原創(chuàng)發(fā)布于微信公眾號「極客猴」,歡迎關(guān)注第一時(shí)間獲取更多原創(chuàng)分享