首页 > 解决方案 > AttributeError:模块'flask_login.login_manager'在使用Flask登录时没有属性'user_loader'而没有模式

问题描述

我有以下代码,我正在尝试使用 Flask 进行身份验证:

from flask import Flask
from flask_login import LoginManager, login_manager
from auth.auth import auth_bp
from environments.environments import environments_bp
from migration.migration import migration_bp
from logs.logs import logs_bp

UPLOAD_FOLDER = 'static/uploads'

@login_manager.user_loader
def load_user(user_id):
    # since the user_id is just the primary key of our user table, use it in the query for the user
    return True

def create_app():

    app = Flask(__name__)

    app.register_blueprint(auth_bp, url_prefix='/auth')
    app.register_blueprint(environments_bp, url_prefix='/environments')
    app.register_blueprint(migration_bp, url_prefix='/migration')
    app.register_blueprint(logs_bp, url_prefix='/logs')

    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
    app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

    login_manager_copy = LoginManager()
    login_manager_copy.login_view = 'auth.login'
    login_manager_copy.init_app(app)

    return app

我没有使用任何数据库,并且身份验证只是硬编码的 if 检查,因为这是用于单次使用的内部工具。

如何解决此错误?

标签: pythonflaskflask-login

解决方案


在您的应用程序工厂中创建 LoginManager() 对象之前,您正在装饰 load_user 函数create_app()

对于一个组织良好的应用程序,您应该配置 LoginManager 以在您的应用程序工厂中与您的应用程序一起使用,就像您现在尝试做的那样。

def create_app():
    app = Flask(__name__)
    ...
    login_manager = LoginManager()
    login_manager.init_app(app)
    ...
    return app

然后在您的授权蓝图login_manager中访问您的应用程序对象代理current_app,并在那里定义您的load_user回调函数

from flask import current_app as app
...
...
@app.login_manager.userloader # Here your app is already created and configured with login manager
def load_user(_id):
    #Get your user from the database or where ever you are storing your user information and construct the user object to return
    if user_found:
      return user
    else:
      return None
...
...

不要忘记他们您还需要save_user调用函数来保存用户(您可以选择将其保存在数据库或您认为合适的任何其他地方)成功登录。

现在,每个请求都会调用这个回调函数,它会重新加载您使用会话中存储的用户 ID(例如 cookie)保存的用户对象。如果它找到具有相应 ID 的用户,它将根据您在load_user回调函数中的逻辑构造用户对象,并且您将拥有一个称为用户代理current_user,您可以在请求的上下文中访问它

例如,在 GET 请求中,您可以执行

if current_user.age < 19:
  raise Unauthorized("Too young to rent a car")

我强烈建议您彻底阅读 Flask-Login 文档,这样会更容易理解流程。


推荐阅读