Session
session 的資料存在資料庫中,它在用戶端是用 cookie 來識別的,作為一個票據。這個 cookie 的名稱,預設就叫 "sessionid",但是可以通過 settings.SESSION_COOKIE_NAME 來修改。
sessionid 這個 cookie 的值,在伺服器端就是 session 的 session_key 屬性,同時資料庫的 django_session 表中用它作為主鍵。
session 的實現涉及下列幾個主要的類:
1. Session 和 SessionManager.
這兩個是 session 的 Model 及其相應的 Manager. 它們負責:
(1) session 和資料庫之間的持久化操作
(2) session_key 的產生機制
(3) session 內容(是一個字典)的序列化/還原序列化工作。
實際應用中,我們不會直接用到這兩個類。
2. SessionWrapper
實現了 session 類似字典的一些功能,如設值、取值等。這個類是 request.session 對象的實際類型。
3. SessionMiddleware
屬於 django 內建的中介軟體之一,作用是在 request 中附加 session 屬性,並可以在 response 的時候,適當的情況下儲存 session 並發出相應的 cookie 到用戶端。
session 的幾個可配置的參數:
settings.SESSION_SAVE_EVERY_REQUEST
settings.SESSION_EXPIRE_AT_BROWSER_CLOSE
settings.SESSION_COOKIE_AGE
settings.SESSION_COOKIE_SECURE
settings.SESSION_COOKIE_DOMAIN
settings.SESSION_COOKIE_NAME
User
request.user 中儲存的 user 對象,是 lazy-load 的,有緩衝。
使用者的身分識別驗證過程:
1. 首先通過 authenticate() 方法對傳入的使用者名稱、密碼等資訊進行驗證,如果符合,則返回相應的 user 對象,同時,該方法會對 user 對象加以標註,通過附加 user.backend 屬性來記錄驗證是被哪個配置的 backend 通過的。預設只有一個
backend,是 django.contrib.auth.backends.ModelBackend.
2. login 方法調用
如果上一步身分識別驗證通過,則此方法中對 request.session 中簡單的添加兩個索引值:
(1) "_auth_user_id" 這個是 user.id
(2) "_auth_user_backend" 這個是 user.backend
而實現 request.user 屬性同樣是通過 Middleware 來完成的,其中調用到一個 get_user 方法,該方法嘗試讀取上面在 session 中記錄的 user.id 和 user.backend, 然後命令 backend 去尋找相關
id 的 user 對象。如果沒有找到,則返回一個 AnonymousUser. 而 AnonymousUser 是一個空實現,不具備 user 的任何功能。
可以通過 is_anonymous() 或 is_authenticated() 來判別是否為匿名使用者。
小結
django 中 user 和 session 關係不大,僅僅是在其實現中利用 session 儲存了 user.id 和 user.backend 兩個值。