How to set cookies in Graphene Python mutation?
Asked Answered
C

2

7

In Graphene Python, how should one go about setting cookies in the schema.py when there is no access to the HttpResponse object to set the cookie on?

My current implementation is to set the cookie by overriding the GraphQLView's dispatch method by catching the data.operationName. This involves hard-coding of the operation names / mutations that I need cookies to be set on.

In 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

Is there a cleaner way of setting cookies for specific Graphene Python mutations?

Crandale answered 17/8, 2017 at 9:8 Comment(0)
C
5

Wound up setting cookies via middleware.

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
        ...

In a custom graphql view, views.py, override the dispatch method to read the cookie and set it.

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
Crandale answered 22/9, 2017 at 12:22 Comment(0)
H
4

I had a similar problem. I needed to be able to set the language cookie in a mutation and ended up using the request instance in combination with a custom middleware.

Here's the simplified code:

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)

The mutation doesn't have access to the response so it temporarily stores the value on the request instance. Once the response has been created a custom middleware retrieves it and sets the 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
Holtz answered 11/2, 2020 at 1:51 Comment(1)
Nice example! Thank you!Confederate

© 2022 - 2024 — McMap. All rights reserved.