Django第十四篇-----Django中的會話
目錄
前言
Django 完全支援匿名會話。通過會話框架可以針對網站的每個訪客儲存和檢索任意的資料。Django 把會話資料儲存在伺服器端,而且對傳送和接收 cookie 的過程做了抽象。cookie 中儲存的是會話 ID,而不是資料本身(除非使用基於 cookie 的後端)——這樣實現更安全。
啟用會話
會話由一箇中間件實現。 django-admin startproject 命令建立的 settings.py 檔案預設已啟用 SessionMid-dleware 。為了保證會話可用, MIDDLEWARE_CLASSES 設定中要列出 'django.contrib.sessions.middleware.Ses-sionMiddleware' 。
如果不想使用會話,可以把 MIDDLEWARE_CLASSES 中的 SessionMiddleware 和 INSTALLED_APPS 中的 'djan-
go.contrib.sessions' 刪掉。這樣能節省少量的開銷。
配置會話引擎
預設情況下,Django 在資料庫中儲存會話(使用 django.contrib.sessions.models.Session 模型)。這樣雖
然方便,但是某些情況下在別處儲存資料速度更快,因此 Django 允許修改配置,把會話資料儲存在檔案系統
或快取中。
使用基於資料庫的會話
如果想把會話儲存在資料庫中,要在 INSTALLED_APPS 設定中新增 'django.contrib.sessions' 。然後,執行manage.py migrate 命令,建立儲存會話資料的資料表。
使用基於快取的會話
如果 CACHES 設定定義了多個快取後端,Django 將使用預設的那個。若想使用其他快取後端,把 SES-SION_CACHE_ALIAS 設為那個後端的名稱。配置好快取之後,在快取中儲存會話資料有兩種方式:
1. 把 SESSION_ENGINE 設為 "django.contrib.sessions.backends.cache" ,使用簡單的快取會話儲存器。此時,會話資料直接儲存在快取中。然而,會話資料可能無法持久儲存,因為快取儲存器空間用完或快取伺服器重啟後資料會丟失。
2. 若想持久儲存快取的會話資料,把 SESSION_ENGINE 設為 "django.contrib.sessions.back-ends.cached_db" 。此時使用的是直寫式快取(write-through cache),寫入快取的資料也會寫入資料庫。如果快取中沒有會話資料,再到資料庫中讀取。
這兩種會話儲存器的速度都十分快,不過簡單快取更快,因為它不做持久儲存。多數情況下, cached_db 後端足夠快了;然而,如果你還需要那最後一點效能,而且想隨著時間的推移擦除會話資料,可以使用 cache後端。如果使用 cached_db 後端,還要按照 15.2.1 節的說明配置。
使用基於檔案的會話
若想使用基於檔案的會話,把 SESSION_ENGINE 設為 "django.contrib.sessions.backends.file" 。你可能還想配置 SESSION_FILE_PATH (預設為 tempfile.gettempdir() 得到的結果,通常是 /tmp ),設定 Django 儲存會話檔案的位置。確保 Web 伺服器有指定位置的讀寫許可權。
會話物件指導方針
• request.session 字典的鍵使用普通的 Python 字串。這不是不得違反的規則,而是一種約定。
• 以下劃線開頭的鍵是保留的,供 Django 內部使用。
• 別使用新物件覆蓋 request.session ,也別訪問或設定它的屬性。像 Python 字典那樣使用它。
會話序列化
在 1.6 版之前,Django 預設使用 pickle 序列化會話資料,然後再存入後端。如果使用的是簽名的 cookie 會話後端,而且攻擊者知道了 SECRET_KEY (Django 沒有內在的漏洞會導致這個金鑰洩露),那麼攻擊者可以在會話中插入字串,反序列化會話後在伺服器中執行任意的程式碼。網上充斥著這種簡而易行的技術。雖然為了防止篡改,cookie 中儲存的是簽名後的會話資料,可是一旦 SECRET_KEY 洩露,遠端執行程式碼的漏洞就凸顯出來了。把序列化會話資料的方式由 pickle 改成 JSON 可以降低這種攻擊的可行性。為此,Django1.5.3 引入了一個新設定,即 SESSION_SERIALIZER ,用於自定義會話的序列化格式。為了向後相容,Django1.5.x 預設使用 django.contrib.sessions.serializers.PickleSerializer ;但是,為了增強安全性,Django1.6 之後預設使用 django.contrib.sessions.serializers.JSONSerializer
持續到瀏覽器關閉的會話與持久會話
可以使用 SESSION_EXPIRE_AT_BROWSER_CLOSE 設定控制會話框架使用持續到瀏覽器關閉的會話還是持久會話SESSION_EXPIRE_AT_BROWSER_CLOSE 的預設值是 False ,這意味著會話 cookie 在使用者的瀏覽器中儲存的時間等
於 SESSION_COOKIE_AGE 。如果不想讓使用者每次開啟瀏覽器後都重新登入,使用這個預設值。
如果把 SESSION_EXPIRE_AT_BROWSER_CLOSE 設為 True ,Django 將使用持續到瀏覽器關閉的會話,即使用者關閉
瀏覽器後會話 cookie 即告過期。
清理會話儲存器
使用者建立的會話不斷積累,佔據著會話儲存器。Django 沒有提供自動清除過期會話的機制,因此你自己要定期清除過期會話。為此,Django 提供了一個清理命令: clearsessions 。建議你定期執行這個命令,比如說定義一個每天執行的 cron 作業。
注意,快取後端不受這個問題的影響,因為快取會自動刪除過期的資料。cookie 亦然,因為會話資料由使用者的瀏覽器儲存。