flsk_login中login_required裝飾器如何起作用:

login_required裝飾器如何起作用:

  • 對於使用了login(user=user, remember=remember…)的用戶, 即爲已登陸的用戶:

login_user方法將user_id remember保存到session中
並將user添加到_request_ctx_stack.top.user中
然後當使用current_user時就會從_request_ctx_stack.top中讀取到user
判斷user的is_authenticated(所有用戶的這個值都爲True)
這裏的語句是:

  if not current_user.is_authenticated:
      return current_app.login_manager.unauthorized()
  return func()

顯然就會調用視圖函數

  • 對於沒有登陸的用戶

同樣的調用這次會執行 current_app.login_mamager.unauthorized()
這個方法返會登陸視圖, 如果沒有指定, 會拋出401的網頁錯誤

current_user = LocalProxy(lambda: _get_user())
_get_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)

_load_user

    config = current_app.config
    if config.get('SESSION_PROTECTION', self.session_protection):
        deleted = self._session_protection()
        if deleted:
            return self.reload_user()

    is_missing_user_id = 'user_id' not in session
    if is_missing_user_id:
        cookie_name = config.get('REMEMBER_COOKIE_NAME', COOKIE_NAME)
        header_name = config.get('AUTH_HEADER_NAME', AUTH_HEADER_NAME)
        has_cookie = (cookie_name in request.cookies and
                        session.get('remember') != 'clear')
        if has_cookie:
            return self._load_from_cookie(request.cookies[cookie_name])
        elif self.request_callback:
            return self._load_from_request(request)
        elif header_name in request.headers:
            return self._load_from_header(request.headers[header_name])

    return self.reload_user()

_load_from_cookie
_load_from_header
_load_from_request

    def _load_from_cookie(self, cookie):
        user_id = decode_cookie(cookie)
        if user_id is not None:
            session['user_id'] = user_id
            session['_fresh'] = False

        self.reload_user()

        if _request_ctx_stack.top.user is not None:
            app = current_app._get_current_object()
            user_loaded_from_cookie.send(app, user=_get_user())

    def _load_from_header(self, header):
        user = None
        if self.header_callback:
            user = self.header_callback(header)
        if user is not None:
            self.reload_user(user=user)
            app = current_app._get_current_object()
            user_loaded_from_header.send(app, user=_get_user())
        else:
            self.reload_user()

    def _load_from_request(self, request):
        user = None
        if self.request_callback:
            user = self.request_callback(request)
        if user is not None:
            self.reload_user(user=user)
            app = current_app._get_current_object()
            user_loaded_from_request.send(app, user=_get_user())
        else:
            self.reload_user()

reload_user()

    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. Refer to"
                    "https://flask-login.readthedocs.io/"
                    "en/latest/#how-it-works for more info.")
            user = self.user_callback(user_id)
            if user is None:
                ctx.user = self.anonymous_user()
            else:
                ctx.user = user
    else:
        ctx.user = user

self.user_callback

    def user_loader(self, callback):
        self.user_callback = callback
        return callback
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章