我在Django之上设置了VueJS SPA。我在/api
上运行了Graphene端点,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'标头,其值由Cookies
提供。截图如下:
不幸的是,Django禁止访问(错误403),并显示消息:“CSRF cookie missing”。
我在网上搜索过但找不到相关内容。
提前致谢!
答案 0 :(得分:3)
TL; DR:问题是标题中没有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添加到标题中并检查 - 它有效。我真的很开心,但想知道为什么一个工作,而另一个则不工作。如上所述,我发现Apollo的请求缺少Cookies Header。实际上XMLHttpRequest
con是你不能在不添加Cookie的情况下发送请求 - 而Fetch API允许你这样做。 Apollo基于Fetch API。我检查了客户端的文档,它就在那里。 :)