天天看點

了解Flask-Login的運作方式

使用者登入過程設計以下步驟:

  1. 使用者

    點選Login連結

    ,eg: http://localhost:5000/auth/login。使用GET請求處理這個URL函數并傳回登入表單模闆。
  2. 使用者輸入使用者名和密碼,點選送出按鈕。再次調用相同處理函數,這次處理的是POST請求

    a. 處理函數驗證通過表單送出的依據,然後調用

    Flask-login

    login_user()

    函數,登入函數

    b.

    login_user()

    函數講使用者ID以字元串形式寫入使用者會話

    c. 視圖函數重定向到指定的登入後跳轉頁面,例如首頁

  3. 浏覽器收到重定向響應,請求頁面

    a. 調用首頁視圖函數, 渲染Jinjia2 模闆

    b. 渲染過程中,首次出現

    Flask-login

    current_user

    的引用

    c. 這個請求還沒有給上下文變量

    current_user

    指派,是以調用

    Flask-login

    内部的

    _get_user()

    函數,找出使用者是誰。
    def _get_user():
    #首先需要知道請求上下文,代碼中的_request_ctx_stack.top中是否有user這個變量,
    # 如果沒有則_load_user
    	if has_request_context() and not hasattr(_request_ctx_stack.top, 'user'):
        	current_app.login_manager._load_user()
    
    return getattr(_request_ctx_stack.top, 'user', None)
               
    def reload_user(self, user=None):
        ctx = _request_ctx_stack.top
    
        if user is None:
            user_id = session.get('user_id')
            if user_id is None:
                ctx.user = self.anonymous_user()
            else:
                if self.user_callback is None:
                    raise Exception(
                        "No user_loader has been installed for this "
                        "LoginManager. Add one with the "
                        "'LoginManager.user_loader' decorator.")
                user = self.user_callback(user_id)
                if user is None:
                    ctx.user = self.anonymous_user()
                else:
                    ctx.user = user
        else:
            ctx.user = user
               
    d.

    _get_user()

    函數檢查使用者會話中有沒有使用者ID,如果沒有,傳回一個

    Flask-login

    AnonymousUser

    執行個體。如果有ID,調用

    user_loader

    裝飾器注冊的函數,傳入使用者ID。

    e. 應用中的

    user_loader

    處理函數從資料庫讀取使用者,将其傳回。

    Flask-login

    把傳回的使用者對象指派給目前請求的

    current_user

    上下文變量。

    f. 模闆接受新指派的

    current_user

使用

login_required

裝飾器裝飾的函數将使用

current_user

上下文變量判斷

current_user.is_authenticated

表達式的結果是否為True。相對的

logout_user

函數就簡單了,直接從使用者會話中把使用者ID删除

摘抄自《Flask Web開發》的8.4.6小節