Flask的session——關於寫擴展所學習到的


這兩天端午節。趁着端午節沒事干,寫了個flask的擴展——flask-RedisSession
在flask中使用該擴展可以讓你借助redis數據庫輕松獲得server-side session.
這個flask擴展可以使用pip install flask-redissession獲得,也可以進入flask-redissession給我個star 給我提問題/建議...

由於寫這個擴展包的需要,我重新研究了一下flask中session的部分。以下部分是我擴展包中的過程。

open_session

當用戶發送請求的時候,request被傳到服務器。由於使用的是server-side session,這個request中就包含一個sessionID。后台程序調用open_session方法,來解析這個request,獲得session。具體的過程如下:

  1. 后台程序解析request,通過session_cookie_name獲得sessionID(如果沒有,就設置為None)

  2. 檢驗這個sessionID是否存在。如果不存在,則生成一個sessionID,然后創建一個session,並返回給客戶端

  3. sessionID存在。檢驗是否使用SECRET_KEY來簽名。如果使用,則調用Signer函數生成Signer對象,並對這個sessionID進行unsigner操作。

    signer = Signer(app.secret_key, salt='flask-redis-session',
                            key_derivation='hmac')
     sessionid = signer.unsign(sessionid).decode('utf-8')
    
  4. 根據unsigner操作獲得的結果在redis數據庫中查找對應的session(已序列化),並對session反序列化。如果根據sessionID沒找到,則創建一個新的session並返回給客戶端

  5. 把查找到的session返回給客戶端

save_session

如果session發生改變,就會調用這個方法(先刪除原session,再set_session)。
在save_session中,我們需要知道:

  1. 把session被序列化后的東西存入redis數據庫:
    以下是序列化的代碼

     serialize_session = self.serialization_method.dumps(dict(session))
    
  2. 需要在每次session發生改變的時候重置過期時間。

  3. 如果使用SECRET_KEY進行簽名,則在給用戶返回sessionID之前,需要對原sessionID進行簽名:

    session_id = Signer(app.secret_key, salt='flask-redis-session',
                                key_derivation='hmac').sign(session.session_id.encode('utf-8'))
    #對session_id進行解碼,轉為str
    session_id = session_id.decode('utf-8')
    
  4. 調用set_session為用戶設置新的session。其中傳輸的值為簽名后的sessionID

總結

  1. redis數據庫使用字符串對象存儲session。
    鍵:未簽名的sessionID
    值:序列化的session
  2. 用戶請求中(request)的sessionID是已簽名sessionID,在服務器中需要unsign操作才能獲得真正的sessionID
  3. 當session發生改變的時候,服務器需要在redis中刪除原session,並調用delete_cookie讓客戶端刪除這個session;然后向redis中寫入新的session(需要序列化),並通過調用set_session把簽名后的sessionID回傳給客戶端


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM