CSRF toner is passed in the header when doing POST

I am setting up a VueJS SPA on top of Django. I have a Graphene endpoint working on /api

, and requests in graphiql

are working fine. I have installed the frontend and I am using Apollo Client to query the server. There goes my setup:

const CSRFtoken = Cookies.get('csrftoken')

const networkInterface = createNetworkInterface({
  uri: '/api',
  transportBatching: true
})

networkInterface.use([{
  applyMiddleware (req, next) {
    if (!req.options.headers) {
      req.options.headers = {}  // Create the header object if needed.
    }
    req.options.headers['X-CSRFToken'] = CSRFtoken
    console.log('applied middleware')
    next()
  }
}])

const apolloClient = new ApolloClient({
  networkInterface,
  connectToDevTools: true
})

Vue.use(VueApollo)

const apolloProvider = new VueApollo({
  defaultClient: apolloClient
})

new Vue({
  el: '#app',
  apolloProvider,
  render: h => h(App)
});

      

My POST requests have a "X-CSRFToken" header with the value provided Cookies

. Screenshot below: Request header

Unfortunately Django denies access (error 403) with the message "CSRF cookie missing".

I have searched the web but cannot find anything related.

Thanks in advance!

+3


source to share


1 answer


TL; DR: The problem is the absence of cookies in the headers including csrftoken

.

To fix this add

  opts: {
    credentials: 'same-origin'
  }

      

to initialize createNetworkInterface

as shown below.

// headers for auth
const networkInterface = createNetworkInterface({
  uri: '//localhost:8000/api',
  transportBatching: true,
  opts: {
    credentials: 'same-origin'
  }
})

      



Long story:

I've been doing this for the past two days asking about Django and Apollo community feeds. I was desperate, so I decided to switch from Apollo to another GraphQL client. I looked at the referenced implementation at http://graphql.org/graphql-js/graphql-clients/ . It looks like this:

var xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.open("POST", "/graphql");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Accept", "application/json");
xhr.onload = function () {
  console.log('data returned:', xhr.response);
}
xhr.send(JSON.stringify({query: "{ hello }"}));

      

I threw it into my code, added a CSRF cookie to the headers and checked - it worked. I was really happy, but wanted to know why it works and the other doesn't. As written above, I found that the Apollo request was missing the Cookies Header. In fact, XMLHttpRequest

con is that you cannot send a request without adding Cookies - while the Fetch API allows you to do this. Apollo is based on the Fetch API. I checked the client documentation and it was there. :)

+2


source







All Articles