將 Session 資料存入資料庫—實作Session Interface
上一篇文章《將Session 資料存入資料庫 — 使用 Flask-Session套件》利用 Flask-Session 套件達成將此 session 存入資料庫的目的。本文將探索如何實作 Session Interface
,藉此了解中間的實作原理。
預備動作
環境的準備和《將Session 資料存入資料庫 — 使用 Flask-Session套件》所述類似,這裡將步驟摘出。本文將使用《Flask Web 開發實戰》第六次活動的程式碼來實作, 請由下列指令從 github去得最新程式碼。
$ git clone https://github.com/win911/flask_class.git
進入虛擬環境後,安裝所需套件:
(venv)$ pip install -r requirement/common.txt
(venv)$ pip install -r requirement/dev.txt
更新資料庫:
(venv)$ python manage.py db upgrade
開發
主要開發步驟歸納如下:
- 新增
sessions
資料表到資料庫 - 新增
sessions.py
實作Session Interface
- 在
__init__.py
加入相關引用
完整的修改程式碼在此 GitHub Commit。
- 新增
sessions
資料表
在 model.py
裡,加入 SessionData
class 如下,主要需要紀錄原本經 Flask-Login 加密後儲存在 cookie 裡的加密資料 (如: user id) - Value
,以及之後用來對應的、存在 cookie 裡的 session id- sid
。
更新資料庫 migration script 並且更新資料庫:
(venv)$python manage.py db migrate
(venv)$python manage.py db upgrade
2. 新增 sessions.py
實作 Session Interface
此篇文章是實作存入 Sqlite
資料庫,因此將自製的 Session Interface
取名為 SqliteSession
。由於 session 相關資料是存入 sessions
資料表,因此從 model.py
import Session Class
來進行資料庫操作。
from .models import Session
根據官方文件說明,要取代Flask 的Session Interface
最少要實作open_session()
和 save_session()
方法,其餘方法不需要改變。其中open_session()
方法是通過參數的請求建立 session 物件並回傳,而 save_session()
方法是將 session 物件儲存到資料庫並透過 response
設定cookie 裡 session 的相關資訊 (如下文所述的set_cookie
指令和delete_cookie
指令 )。
open_session()
方法需要回傳 session 物件,此 session 物件由自行撰寫的 SqliteSession Class (繼承 CallbackDict 和 SessionMixin 來提供需要的屬性和方法) 提供。
open_session()
方法會依據 request
是否能取得 session id (sid) ,決定是要產生新的 sid
,或者以此 sid
到資料庫取得 session 資料,並回傳上面定義的 session 物件。
在 save_session()
方法,如果 session 內的資料被清空,在 response
回傳 delete_cookie
指令。如果取得 session 資料,透過 pickle 進行序列化後儲存在 sessions 資料表的 value 欄位。並且在 response
回傳 set_cookie
指令。
3. 在 __init__.py 加入相關引用
在一切備齊後,在 app 起始時以 SqliteSessionInterface
取代原本預設 session_interface
。
4. 啟動網站
(venv)$python manage.py runserver
如果上述開發正確進行,網站啟動後一切所有功能運作正常,存在cookie 裡的session 資料會是 session id,不是原本使用 Flask-Login,預設將 Session 資料加密存入 Cookie。
參考資料
- PyLadies Taiwan: Facebook 粉絲頁、Meetup
- Flask 官方文件: Session Interface