如何在 Graphene Python 突变中设置 cookie?

Posted

技术标签:

【中文标题】如何在 Graphene Python 突变中设置 cookie?【英文标题】:How to set cookies in Graphene Python mutation? 【发布时间】:2018-01-25 14:55:36 【问题描述】:

在Graphene Python 中,当无法访问HttpResponse 对象来设置cookie 时,应该如何在schema.py 中设置cookie?

我当前的实现是通过捕获data.operationName 覆盖GraphQLView 的调度方法来设置cookie。这涉及对我需要设置 cookie 的操作名称/突变进行硬编码。

在views.py中:

class PrivateGraphQLView(GraphQLView):
    data = self.parse_body(request)
    operation_name = data.get('operationName')
    # hard-coding === not pretty.
    if operation_name in ['loginUser', 'createUser']:
        ...
        response.set_cookie(...)
    return response

是否有更简洁的方式为特定的 Graphene Python 突变设置 cookie?

【问题讨论】:

【参考方案1】:

最终通过中间件设置 cookie。

class CookieMiddleware(object):

    def resolve(self, next, root, args, context, info):
        """
        Set cookies based on the name/type of the GraphQL operation
        """

        # set cookie here and pass to dispatch method later to set in response
        ...

在自定义 graphql 视图中,views.py,重写 dispatch 方法以读取 cookie 并设置它。

class MyCustomGraphQLView(GraphQLView):  

    def dispatch(self, request, *args, **kwargs):
        response = super(MyCustomGraphQLView, self).dispatch(request, *args, **kwargs)
        # Set response cookies defined in middleware
        if response.status_code == 200:
            try:
                response_cookies = getattr(request, CookieMiddleware.MIDDLEWARE_COOKIES)
            except:
                pass
            else:
                for cookie in response_cookies:
                    response.set_cookie(cookie.get('key'), cookie.get('value'), **cookie.get('kwargs'))
        return response

【讨论】:

【参考方案2】:

我遇到了类似的问题。我需要能够在突变中设置语言 cookie,并最终将请求实例与自定义中间件结合使用。

这是简化的代码:

class SetLanguage(Mutation):
    class Arguments:
        code = String(required=True)

    ok = Field(Boolean)
    language = Field(LanguageType)

    def mutate(root, info, code):
        info.context.set_language_cookie = code
        return SetLanguage(ok=True, language=code)

突变无权访问响应,因此它临时将值存储在请求实例上。创建响应后,自定义中间件会检索它并设置 cookie:

class LanguageConfigMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)

        if code := getattr(request, "set_language_cookie", None):
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, code)

        return response

【讨论】:

很好的例子!谢谢!

以上是关于如何在 Graphene Python 突变中设置 cookie?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 graphene-django 定义突变的自定义输出类型?

如何删除 Graphene Django 突变查询(中继)中的嵌套输入对象?

如何在 Python 中验证 GraphQL 突变

Django Graphene 使用多层嵌套外键编写突变

如何查看graphene-django DEBUG日志

在单个 GraphQL 突变(graphene-django)中返回已删除对象的数组