Как я могу передать 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))