Flask-Security,在蓝图中实现 SECURITY_TRACKABLE 功能

Flask-Security, implement SECURITY_TRACKABLE feature in Blueprint

我正在使用 Flask-Security 的 SECURITY_TRACKABLE 功能,在我的自定义 API 登录请求处理程序中,我试图确保按照 flask-security documentation on login_user().

我的登录代码在蓝图中:

from modules.auth.models import User
from flask import Blueprint, request, abort
from flask_restful import Api, Resource
from flask_security import login_required
from flask_security.utils import verify_password, login_user, logout_user 

app = Blueprint(__name__, __name__)
api = Api(app)

class LogResource(Resource):
    """
    Manages user login and logout
    """

    def post(self):
        user = User.query.filter_by(
            email = request.form['email']
        ).first()
        if not user:
            abort(401, "Wrong credentials.")

        if verify_password(request.form['password'], user.password):
            login_user(user)
            app.security.datastore.commit()
            return "Logged in"
        else:
            abort(401, description="Wrong credentials.")

但是当用户登录时我得到了错误:AttributeError: 'Blueprint' object has no attribute 'security',因为我在蓝图中而不是在应用程序中。我该如何解决这个问题?

Security() 对象永远不是 Flask 应用程序对象的直接属性。你这里的错误是 app 是一个 Blueprint 对象,这更容易混淆。无论如何,您通常 app 用于蓝图对象。

您可以导入您首先创建Security(...)实例的模块中的对象,或者您可以通过Flask访问它extensions 映射通过 current_app reference:

from flask import current_app

security = current_app.extensions['security']  # or reference .datastore, etc.

接下来,您通常希望在响应完成后提交访问权限,因为这有助于更快地为最终用户生成结果并让您记录响应状态。使用 after_this_request() function 到 运行 响应后的提交:

from flask import current_app, after_this_request

def flask_security_datastore_commit(response=None):
    datastore = current_app.extensions['security'].datastore
    datastore.commit()
    return response

并且在您看来使用:

if verify_password(request.form['password'], user.password):
    login_user(user)
    after_this_request(flask_security_datastore_commit)
    return "Logged in"