將 Session 資料存入資料庫—實作Session Interface

Pei Cheng
PyLadies Taiwan
Published in
4 min readMay 12, 2018

上一篇文章《將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

開發

主要開發步驟歸納如下:

  1. 新增 sessions 資料表到資料庫
  2. 新增 sessions.py 實作 Session Interface
  3. __init__.py 加入相關引用

完整的修改程式碼在此 GitHub Commit

  1. 新增 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

根據官方文件說明,要取代FlaskSession Interface 最少要實作open_session()save_session() 方法,其餘方法不需要改變。其中open_session() 方法是通過參數的請求建立 session 物件並回傳,而 save_session() 方法是將 session 物件儲存到資料庫並透過 response 設定cookiesession 的相關資訊 (如下文所述的set_cookie 指令和delete_cookie 指令 )。

open_session() 方法需要回傳 session 物件,此 session 物件由自行撰寫的 SqliteSession Class (繼承 CallbackDictSessionMixin 來提供需要的屬性和方法) 提供。

Session 物件

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。

實作 Session Interface 後,cookie 長度變短

參考資料

--

--