我有一个烧瓶应用程序,它使用烧瓶安全性进行身份验证我想使用带有graphene的graphql来获取数据,但我无法访问current_user代理,而我一直用它来解析请求。石墨烯只提供定制的pluggable view,这是可以理解的,但它无法在应用程序的上下文中访问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部分。
我有基本的Query类,在其中,我想访问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()
如果有人能修好这段代码并让我摆脱这种大脑放屁,我真的很感激。
答案 0 :(得分:0)
代码中的主要问题是
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))