如何将curent_user从flask-security传递给可插拔的视图函数?

时间:2018-01-07 02:17:37

标签: flask flask-sqlalchemy graphql flask-security graphene-python

我有一个烧瓶应用程序,它使用烧瓶安全性进行身份验证我想使用带有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()

如果有人能修好这段代码并让我摆脱这种大脑放屁,我真的很感激。

1 个答案:

答案 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))