Как я могу передать curent_user из flask-security в подключаемую функцию просмотра?

У меня есть приложение фляги, которое использует безопасность фляги для аутентификации. Я хочу использовать graphql с графеном для извлечения данных, но у меня возникают проблемы с доступом к прокси-серверу current_user, который я всегда использовал для разрешения запросов. Графен предоставляет только настраиваемое подключаемое представление, которое понятно, но оно не может получить доступ к current_user в контексте приложения и, следовательно, current_user возвращается к AnonymousUser.

вот пример кода

from flask import Flask, render_template, redirect, request
from flask_security import Security, SQLAlchemySessionUserDatastore, login_required, current_user, login_user

from flask_graphql import GraphQLView
import graphene
from graphene_sqlalchemy import SQLAlchemyConnectionField

from .models import UserModel, RoleModel, Todo, TodoModel
from .pipeline import session

app = Flask(__name__, template_folder="../templates", static_folder="../static")
app.config.from_object('core.pipeline.configs.DevConfig')
user_datastore = SQLAlchemySessionUserDatastore(session, UserModel, RoleModel)
security = Security(app, user_datastore)

@app.route('/')
@login_required
def index(path):
    user = current_user

    return render_template('index.html')

пока тривиально, выше только для контекста. Модели являются стандартными sqlalchemy в соответствии с примерами документации. Я могу легко получить доступ к current_user при маршрутизации с декораторами.

Теперь перейдем к части graphql.

У меня есть базовый класс запросов, и в нем я хотел бы получить доступ к current_user.

class Query(graphene.ObjectType):
    Todo = SQLAlchemyConnectionField(Todo)

    def resolve_todo(self, args, context, info):
        query = Todo.get_query(context)
        return query.filter(TodoModel.user_id == current_user.id) ## USE HERE TO RESOLVE

Я использую класс Query для создания функции представления из GraphQLView, которая сама является расширением MethodView. Это заставляет меня использовать app.add_url_rule в отличие от простых декораторов, и я не могу понять, как передать current_user

с помощью небольшой вспомогательной функции передайте функцию просмотра url_rules.... И застрял!!!

def graphql_view():
    schema = graphene.Schema(query=Query)
    context = {'session': session}
    graphiql = bool(app.config.get("DEBUG", False))
    return GraphQLView.as_view('graphql', schema=schema, context=context, graphiql=graphiql)


app.add_url_rule('/graphql', view_func=graphql_view())

@app.teardown_appcontext
def shutdown_session(exception=None):
    session.remove()

Буду очень признателен, если кто-нибудь сможет исправить этот код и освободить меня от этого пердежа мозга.

1 ответ

Основная проблема в вашем коде

app.add_url_rule('/graphql', view_func=graphql_view())

Где graphql_view () запускается во время загрузки кода без контекста запроса колбы.

Пожалуйста, попробуйте этот код

class GraphQLViewCurrentUser(GraphQLView):

    def get_context(self, request):
        context = super().get_context(request)
        context.update({'current_user': current_user})
        return context


app.add_url_rule(
    '/graphql', view_func=GraphQLViewCurrentUser.as_view(
        'graphql', schema=schema, context={}, graphiql=True))
Другие вопросы по тегам