执行 POST 时,CSRF 令牌在 header 中传递

CSRF token gets passed in the header when performing POST

我正在 Django 之上设置 VueJS SPA。我在 /api 上有石墨烯端点 运行ning 并且在 graphiql 运行 中查询很好。我已经设置了前端并且正在使用 Apollo Client 来查询服务器。我的设置是:

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)
});

我的 POST 请求有 'X-CSRFToken' header,其值由 Cookies 提供。截图如下:

不幸的是,Django 禁止访问(错误 403),消息为:"CSRF cookie missing".

我在网上搜索过,但找不到任何相关内容。

提前致谢!

TL;DR:问题是 headers 中缺少 cookie,包括 csrftoken

要解决此问题,请附加

  opts: {
    credentials: 'same-origin'
  }

createNetworkInterface初始化,如下所示。

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

长话短说:

最近两天我一直在摆弄这个,在 Django 和 Apollo 社区频道上四处询问。我真的很绝望,所以我考虑从 Apollo 切换到其他 GraphQL 客户端。我在 http://graphql.org/graphql-js/graphql-clients/ 查看了参考实现。它看起来像这样:

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 }"}));

我已将它放入我的代码中,将 CSRF 令牌 cookie 添加到 headers 中并检查 - 它有效。我真的很高兴,但想知道为什么一个有效,而另一个无效。如上所述,我发现Apollo的请求缺少CookiesHeader。实际上 XMLHttpRequest 缺点是您不能在不添加 Cookie 的情况下发送请求 - 而 Fetch API 允许您这样做。而 Apollo 基于 Fetch API。我检查了客户的文档,它就在那里。 :)