flask 狀態保持session和上下文session的區別


問題場景:

  在falsk項目中導入了兩個session:

    首先,配置文件config.py文件中 有個 flask_session擴展導入了Session  ( from flask_session import Session );

  然后,在login.py文件的登錄接口中  有從flask導入了session   (from flask import session);

先闡述一下狀態保持的概念以及瀏覽器服務器如何實現狀態保持:

  1 狀態保持:
    有時需要保持下來用戶瀏覽的狀態,比如用戶是否登錄過,瀏覽過哪些商品等,
    實現狀態保持主要有兩種方式:使用Cookie在客戶端存儲信息,使用Session在服務器端存儲信息

    1.1.Cookie:
    ▪Cookie是由服務器端生成,發送給客戶端瀏覽器,瀏覽器會將Cookie的key/value保存,下次請求同一網站時就發送該Cookie給服務器(前提是瀏覽器設置為啟用cookie)。

    ▪應用:最典型的應用是判定注冊用戶是否已經登錄網站,用戶可能會得到提示,是否在下一次進入此網站時保留用戶信息以便簡化登錄手續,這些都是Cookie的功用。
    ▪提示:Cookie基於域名安全,不同域名的Cookie是不能互相訪問的
如:訪問jingdong.com時向瀏覽器中寫了Cookie信息,使用同一瀏覽器訪問baidu.com時,無法訪問到jingdong.com寫的Cookie信息,瀏覽器的同源策略。

    1.2.session:
對於敏感、重要的信息,建議要存儲在服務器端,不能存儲在瀏覽器中,如用戶名、余額、等級、驗證碼等信息,在服務器端進行狀態保持的方案就是Session,Session依賴於Cookie

  2、區別:

    2.1  當然,在flask項目中也要實現狀態保持,把Cookie存儲在瀏覽器,session存儲到服務器,但是當我們的用戶量較大時,各種狀態保持信息(用戶信息,瀏覽歷史信息等)都放到session中,就會大大的增加服務器的負荷,為了減輕服務器的壓力,我們就把session放到redis數據庫中,另外,redis數據庫讀取數據也是更快的,這個功能的實現靠的就是flask-session擴展中的Session;  即session是基於瀏覽器的cookie進行保存在服務器上的,flask_session可以把session的值存儲在redis數據庫中。這個session無論用戶登錄還是退出,只要不過期,就一直存在,與框架無關,與語言無關,便於用戶在瀏覽器端再次便捷登錄。

    2.2  from flask import session  這個sesssion是flask框架內置的請求上下文對象,用來操作記錄http請求的數據或session信息,在請求過程中存在,請求結束后就被銷毀;比如只有登錄的用戶並且發送http請求時,它才被喚醒存儲內容,用戶退出時,它又被銷毀;在本flask項目的應用場景:

      (1) 在登錄接口,用戶用過mobile 和password驗證后(用戶存在且密碼正確),我們就通過mobile查詢出該用戶對象user, 再把該登錄用戶的name,user_id, mobile 保存到上下文session中,方便其他模塊接口的調用當前登陸的用戶信息。

      (2) 在登錄接口實現登陸以后,我們如何在其他接口判斷用戶是否登錄呢?很簡單,我們只需用user_id = session.get("user_id"),如果user_id存在,就說明用戶已經通過了登錄接口的驗證和session信息的保存。因為很多接口都要判斷登錄狀態,我們通常把這個功能放到裝飾其中(即重寫flask_login的login_required方法),方便各接口調用

    在utils/common.py文件中重寫login_required方法:

    

 1 def login_required(func):
 2     '''檢查用戶的登錄狀態'''
 3     @wraps(func)
 4     def wrapper(*args, **kwargs):
 5         # 核心邏輯 獲取session的id
 6         user_id = session.get('user_id')
 7         if user_id is not None:
 8             # 表示用戶已經登錄 
 9             # 后面的接口仍需要user_id數據,來獲取當前登陸的用戶
10             # 為了方便,可以使用g變量來記錄,避免多次訪問保存session的redis服務器或項目服務器(根據session存放的位置)
11             g.user_id = user_id
12             return func(*args, **kwargs)
13         else:
14             retrun jsonify(error='4005', errmsg='用戶未登錄')
15      return wrapper

    在其他接口的應用:(判斷是否登錄和獲取登錄用戶id,這也是login_required的兩個功能, 不重寫的話只有判斷功能)

 1 from ihome.utils.common import login_required
 2 
 3 @api.route("/sessions", methods=["DELETE"])
 4 @login_required    # 驗證登錄裝飾器
 5 def logout():
 6     """登出"""
 7     # 清除session數據, csrf_token需要保留.
 8     csrf_token = session['csrf_token']
 9     session.clear()
10     session['csrf_token'] = csrf_token
11 
12     # 刪除session的方式:3種
13     # 1.session.pop()  2. 和Django所學相同  3. session.clear()全部刪除
14 
15     return jsonify(errno=RET.OK, errmsg="OK")

 


免責聲明!

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



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