I use graphene-django
. Creating an application, GraphiQL
worked well for login and other functions. But when I use Insomnia
, I get a 403 Forbidden
error.
I referred to this documentation, https://github.com/howtographql/howtographql/blob/master/content/backend/graphql-python/4-authentication.md
And I tried:
csrf_exempt
; It works fine, but of course I will not use it.django-cors-headers
; It does not work well.How can I solve this 403
error?
I would not recommend @yestema 's second method to work around the problem you are facing.
GET
methods for querying your GraphQL endpointIf one wants to implements this workaround and is also using Graphql for mutations
, it looks like bad design.
It has been established as a standard that GET
requests must not alter the state of the server nor the database, and mutations
are, most of the times, used for altering the state of one or another (probably only the database, since your app should be stateless).
Note that you could also use query
methods to alter the state of your backend, but, again, this would be against the established standard, as explained in the grapqhl documentation:
[...] In REST, any request might end up causing some side-effects on the server, but by convention it's suggested that one doesn't use GET requests to modify data. GraphQL is similar - technically any query could be implemented to cause a data write. However, it's useful to establish a convention that any operations that cause writes should be sent explicitly via a mutation.
csrf_exempt
decorator?To give hints to people wondering how bad it is to get rid of the default CSRF checks, here is my two cents explanation.
A service is exposed to CSRF attacks when the authentication parameters are automatically sent by the browser, which is the case with the default Django's authentication system, based on sessions.
If you use your Django app only as an API backend, chances are that you rely on another authentication mechanism, such as DRF's TokenAuthentication or some kind of JWT implementation.
Basically, these authentication systems are immune to CSRF attacks, because if a malicious website wants to access your server on behalf of your users — which is what CSRF is all about —, it won't be able to set the Authorization
HTTP header expected by your server to actually authenticate the request (provided that you stored the token securely, in a cookie only accessible by your front application domain...).
tl;dr
Keep sending your GraphQL queries with POST
requests, this is the best practice.
If your GraphQL endpoint is accessible only by authenticated users and your authentication system does not rely on Django's sessions, it's OK to exempt your endpoint from CSRF checking.
However, if you use the Django's default authentication system — ie, a sessionid
stored in a cookie, then you must enforce the csrf
verification.
At this point, your only chance is, as said by previous answers, to add the X-CSRFToken
header in your HTTP requests, and give it the value of the csrftoken
cookie that was automatically set by previous requests to the server.
I initially posted this answer on GitHub, but thought it could be useful also here.
What you are looking for is csrf_exempt
in your url(r'^graphql', csrf_exempt(GraphQLView.as_view(graphiql=True))),
You can import it like this: from django.views.decorators.csrf import csrf_exempt
.
csrf token is not required on the GraphQL endpoint, since it is an API.
CSRF tokens are required in production by default because django doesn't know which POST request is for a form and which isn't. Also CSRF might be useful in the case you want to use the GraphQL endpoint only on your website (so having the token is an additional security measure). But for you case it is totally fine to remove the CSRF token check in production.
Var. 1)
Set Header X-CSRFToken
(also you can try X-CSRFTOKEN
and csrftoken
)
Var. 2) Not very correct solution, but it's easy & it works! Use GET request instead of POST. Somehow it works...
OR
Var. 3) Didn't work for me Also. You can try go right way and add to cookie X-CSRFTOKEN a) click Cookie TAB b) Manage Cookie button c) Actions -> Add Cookie P.S. Actually Insomnia inject csrftoken automaticly, you can try usual REST POST and you will see, that it works fine and there is csrftoken automaticly added by insomnia...
If you want to use CSRF middleware with Graphene then you need to set CSRF token in the cookie of your request headers.
I don't have experience with Insomnia but I am sure it will let you customize request header, like Apollo link does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With