I'm working on a project using Django as backend, Vue as frontend, and trying to implement Apollo/Graphene/GraphQL as data transfer layer. Most of it works, but I don't get my head around the CORS/CSRF settings.
(Had really much research here. here, and here and here.
Does anyone know how to solve securing the graphql/graphene API via a CSRF token? On the django log terminal, I get:
Forbidden (CSRF token missing or incorrect.): /graphql/
...while on the Vue/Js Console I see
Cross-Origin Request Blocked: The Same Origin Policy disallows
reading the remote resource at http://localhost:8080/sockjs-node/
info?t=1558447812102.
You can see (and checkout, it's open source) this project here.
http://localhost:8000, http://localhost:8000/admin and http://localhost:8000/ work nicely. The query query{menuItems{id, title, slug, disabled}}
works well in graphiql.
settings.py:
INSTALLED_APPS = [
# ...
'corsheaders',
'rest_framework',
'webpack_loader',
'graphene_django',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # new
# ...
]
CORS_ORIGIN_ALLOW_ALL = DEBUG # (=True)
The problem is here:
* yarn serve
is running on http://localhost:8080
* ./manage.py runserver
is running on http://localhost:8000, and proxies through webpack the Vue frontend dev server.
vue.config.js:
module.exports = {
// The base URL your application bundle will be deployed at
publicPath: 'http://localhost:8080',
// ...
chainWebpack: config => {
// ...
config.devServer
.public('http://localhost:8080')
// ...
vue-apollo.js:
const httpEndpoint = process.env.VUE_APP_GRAPHQL_HTTP || 'http://localhost:8000/graphql/'
EDIT: If I wrap the graphql/
api urlpath with csrf_exempt
, it works:
urlpatterns = [ # ...
path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))),
]
But this is a BadIdea(TM) securitywise. How can I get that token into the frontend using Vue with Django and webpack_loader?
It's probably fine to skip CSRF check for that request, but it's hart t assess it from information you've given, so let me explain why do we need CSRF checks at the first place.
CSRF was created to fix a "hole" that is present in how HTTP and web browsers work. This hole goes as follows: any website can contain a from that submits data to your website, and when doing so, cookies will be passed along the form submitted by user.
This means that 3rd party website can trick your users to perform some action on your website. To prevent that, idea of CSRF tokens was created. Simply put: any form on your website that is responsible for performing any action that can be in any way harmful for user when tricked by 3rd party website to submit it, has to contain a CSRF token field next to all data being submitted for this action. The same CSRF token needs to be present either in user's session or in cookies. When form is submitted, those 2 tokens are compared and if they don't match or any of them doesn't exist, form will be rejected.
This protects any form to be submitted by 3rd party website, because cookies from your website cannot be read by other websites, even if they are passed along with request coming from such website. It is impossible then for that website to set matching token in form data.
That being said, this issue is not present when you are not keeping user sessions by using cookies. It is also not an issue when your frontend is on separate domain, as all requests coming from your frontend will have Origin
header with it's domain name. So if either of those is the case, you can disable CSRF checks accordingly:
CSRF_TRUSTED_ORIGINS
to whitelist it.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