I'm looking to write a custom middleware for my GraphQL endpoint using PyJWT
. The problem is that I don't want to protect my login mutation. So I'm trying to write the Middleware to exclude the login mutation.
This was easy to do by writing a GraphQL middleware because the arguments passed to the Middleware provided me with the ability to check the name of the query.
class JWTMiddleware(object):
def resolve(self, next, root, info, **args):
if info.field_name == 'login':
return next(root, info, **args
# rest of auth logic
But because GraphQL always returns 200
, I can't use the status code as my auth failure check on my client. And would have to check the errors
array to see if the message is Unauthorized
or something.
Example Error Response:
{
errors: [
{
message: 'Unauthorized: JWT invalid',
...,
},
...
],
data: null
}
This is fine but I would prefer to use the status code of the response as my check so I decided to wrap the GraphQL view with a custom decorator.
def jwt_required(fn):
def wrapper(request):
# no access to query name, just the GraphQLString
# need function to parse the AST of a GraphQLString
graphql_string = request.body.decode('utf-8')
query_name = ast[0].name # or something like this
if query_name == 'login':
return fn(request)
# rest of auth logic
return fn(request)
return wrapper
def protected_graphql_view():
return jwt_required(GraphQLView.as_view())
urlpatterns = [
path('admin/', admin.site.urls),
path('graphiql', GraphQLView.as_view(graphiql=True)),
path('graphql', protected_graphql_view()),
path('token/refresh', refresh_token_view),
]
By doing it like this I now can return Responses with different status codes. But again the problem is I can't easily check if the request is for login and skip the auth logic unless I can parse the GraphQLString correctly.
I would prefer to not custom make something, if possible. I would assume GraphQL or Graphene would provide something like this.
Please let me know if I need to provide anymore information. Thank you for any help!