Flask-Security, внедрить функцию SECURITY_TRACKABLE в Blueprint - PullRequest
0 голосов
/ 27 октября 2018

Я использую функцию SECURITY_TRACKABLE для Flask-Security, и в своем обработчике запросов на вход в пользовательский API я пытаюсь убедиться в том, что зафиксировал изменения в хранилище данных, как того требует документация во флеш-безопасности 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', потому что я в чертеже, а не в приложении. Как я могу это исправить?

1 Ответ

0 голосов
/ 27 октября 2018

Объект Security() никогда не является прямым атрибутом объекта приложения Flask. Ваша ошибка здесь в том, что app - это Blueprint объект, что еще больше сбивает с толку. Вы обычно должны не использовать app для объекта чертежа в любом случае.

Вы можете импортировать объект из модуля, где вы сначала создаете экземпляр Security(...), или вы можете получить к нему доступ через отображение Flask extensions через current_app ссылка :

from flask import current_app

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

Далее, как правило, вы хотите зафиксировать доступ после завершения ответа , поскольку это помогает получить более быстрый результат для конечного пользователя и позволяет также записывать состояние ответа. Используйте функцию after_this_request() для запуска фиксации после ответа:

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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...