我有以下代码,我正在尝试使用 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
我没有使用任何数据库,身份验证只是硬编码的检查,因为这是用于单次使用的内部工具。
如何修复此错误?
在应用工厂中创建 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 文档,这会让你更容易理解流程。
数字海洋教程后来到这里。请按照以下代码操作,就可以开始了。
from flask import Flask,request
from flask_migrate import Migrate
from .routes import auth
from flask import g
from .models.models import db
from flask_babel import Babel
from .settings import config
from flask_login import LoginManager
from .models.models import User
from .settings import config
import json
login_manager = LoginManager()
app = Flask(__name__)
app.config['SECRET_KEY'] = config['SECRET_KEY']
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite3'
app.config['BABEL_DEFAULT_LOCALE'] = config["DEFAULT_LOCALE"]
def get_locale():
lang = request.args.get('lang','en')
if not lang in config["AVAILABLE_LOCALE"]:
lang = config["DEFAULT_LOCALE"]
request.accept_languages.best_match(config["AVAILABLE_LOCALE"])
return lang
babel = Babel(app,locale_selector=get_locale)
db.init_app(app)
migrate = Migrate(app, db)
login_manager.login_view = config["LOGIN_PATH"]
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
login_manager.init_app(app)
# register the route here
app.register_blueprint(auth.bp)
def create_app():
g.debug = config["DEBUG"]
return app