gpt4 book ai didi

django - Graphite 烯 django 端点是否同时需要 X-Csrftoken 和 CsrfCookie?

转载 作者:行者123 更新时间:2023-12-05 03:54:59 30 4
gpt4 key购买 nike

使用:

  • Django 3.x [Django-Filters 2.2.0、graphene-django 2.8.0、graphql-relay 2.0.1]
  • Vue 2.x [Vue-Apollo]

我正在使用 Django、GraphQL 和 Vue-Apollo 测试单页 Vue 应用程序。

如果我在我的 View 中使用 csrf_exempt,那么一切都在前端工作。

urlpatterns = [
<...>
path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True))),
<...>

现在我想用 CSRF 保护我的请求。在理解 CSRF 保护的过程中,我认为所有 Django GraphQLView 需要的是在请求 header 中接收 X-Csrftoken 的“值”。所以我专注于以不同的方式发送 csrf 值......通过像这样的单一 View

path('csrf/', views.csrf),
path("graphql", GraphQLView.as_view(graphiql=True)),

或使用 ensure_csrf_cookie 确保 cookie

之后,在我的 ApolloClient 中,我获取这些 Value 并将其与请求 Header 一起发回。

这是我从 Django-Vue 页面发送 GraphQL 请求时 Django 打印的内容。

Forbidden (CSRF token missing or incorrect.): /graphql

Parallel 我总是使用 graphiql IDE 进行测试,这些请求仍然有效。我还每次打印查询解析器的 info.context.headers 值。

{'Content-Length': '400', 'Content-Type': 'application/json',
'Host': 'localhost:7000', 'Connection': 'keep-alive',
'Pragma': 'no-cache', 'Cache-Control': 'no-cache',
'Accept': 'application/json', 'Sec-Fetch-Dest': 'empty', 'X-Csrftoken': 'dvMXuYfAXowxRGtwSVYQmpNcpGrLSR7RuUnc4IbIarjljxACtaozy3Jgp3YOkMGz',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36',
'Origin': 'http://localhost:7000',
'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'cors',
'Referer': 'http://localhost:7000/graphql', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9,de;q=0.8',
'Cookie': 'sessionid=jqjvjfvg4sjmp7nkeunebqos8c7onhiz; csrftoken=dvMXuYfAXowxRGtwSVYQmpNcpGrLSR7RuUnc4IbIarjljxACtaozy3Jgp3YOkMGz'}

我认识到 GraphQLView IDE 总是将 X-CsrftokenCookie:..csrftoken. 也放在请求中。如果在发送请求之前删除 GraphQLView IDE 的 csrftoken-cookie,我会得到这个

Forbidden (CSRF cookie not set.): /graphql

IDE 显示一个长长的红色报告

.... CSRF verification failed. Request aborted.</p>\n\n\n  
<p>You are seeing this message because this site requires a CSRF cookie when submitting forms.
This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p>\n

IDE 的信息说请求需要一个 CSRF cookie。但到目前为止,在论坛、Doc 上阅读的所有内容都与值(value)本身更相关。这意味着您只需要将 header 中的 csrf 值作为 X-Csrftoken 左右发送,View 就会发挥作用。


问题

因此我的问题是:

我是否必须在我的 ApolloClient 中同时设置 X-CsrftokenCookie:..csrftoken 才能制作一个在我的 django GraphQLView 上请求?

或者是否也可以只发送 X-Csrftoken 而没有 csrf-cookie ,反之亦然?

最佳答案

经过长时间的停顿来关注这个问题,我再次尝试并找到了解决方案。

设置

  • django 3.1
  • vue 2.6
  • vue-apollo 3.0.4(支持新的 Apollo-Client 3)
  • @apollo/client 3.1.3

推定

  • 我将 Vue 作为一个多应用程序使用,而不是单个应用程序。
  • 在 Django STATICFILES_DIRS 中编写我的 *vue.js 文件时,Webpack DevServer 将热重载。 Django 将从那里获取文件。工作正常

问题回顾

重新审视我的问题后,我发现我有 2 个问题。一个是浏览器因为 CORS 而拒绝了 graphQL 请求。第二个是 CSRF token 。


解决方案

为了修复 CORS 问题,我注意到我的 Apollo 客户端的 uri 与我的 Django Dev Server 不同。 http://127.0.0.1:7000/graphql 被设置为 http://localhost:7000/graphql。我还设置了 credentials(参见 vue-apollo.js)

为了修复 CSRF,我做了 3 件事

  • 确保发送一个 {% csrf_token %},其中包含您的 Vue/GraphQL 客户端应用 Hook 的 HTML。以便我们稍后获取它。
  • 安装js-cookie获取Cookie
  • vue-apollo.js 中使用 X-CSRFToken 在 Apollo Client Constructor 中设置 header

vue-apollo.js


import Vue from 'vue'
// import path for the new Apollo Client 3 and Vue-Apollo
import { ApolloClient, InMemoryCache } from '@apollo/client/core';
import VueApollo from 'vue-apollo'
import Cookies from 'js-cookie'


// Create the apollo client
const apolloClient = new ApolloClient({
// -------------------
// # Required Fields #
// -------------------
// URI - GraphQL Endpoint
uri: 'http://127.0.0.1:7000/graphql',
// Cache
cache: new InMemoryCache(),

// -------------------
// # Optional Fields #
// -------------------
// DevBrowserConsole
connectToDevTools: true,
// Else
credentials: 'same-origin',
headers: {
'X-CSRFToken': Cookies.get('csrftoken')
}
});

// create Vue-Apollo Instance
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})

// Install the vue plugin
Vue.use(VueApollo)

export default apolloProvider

Vue.config.js


const BundleTracker = require("webpack-bundle-tracker");

// hook your apps
const pages = {
'page_1': {
entry: './src/page_1.js',
chunks: ['chunk-vendors']
},
'page_2': {
entry: './src/page_2.js',
chunks: ['chunk-vendors']
},
}

module.exports = {
pages: pages,
filenameHashing: false,
productionSourceMap: false,

// puplicPath:
// Tells Django where do find the bundle.
publicPath: '/static/',

// outputDir:
// The directory where the production build files will be generated - STATICFILES_DIRS
outputDir: '../dev_static/vue_bundle',


chainWebpack: config => {

config.optimization
.splitChunks({
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "chunk-vendors",
chunks: "all",
priority: 1
},
},
});


// Don´t create Templates because we using Django Templates
Object.keys(pages).forEach(page => {
config.plugins.delete(`html-${page}`);
config.plugins.delete(`preload-${page}`);
config.plugins.delete(`prefetch-${page}`);
})

// create webpack-stats.json.
// This file will describe the bundles produced by this build process.
// used eventually by django-webpack-loader
config
.plugin('BundleTracker')
.use(BundleTracker, [{filename: '/webpack-stats.json'}]);


// added to use ApolloQuery Tag (Apollo Components) see vue-apollo documentation
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.transpileOptions = {
transforms: {
dangerousTaggedTemplateString: true,
},
}
return options
})

// This will allows us to reference paths to static
// files within our Vue component as <img src="~__STATIC__/logo.png">
config.resolve.alias
.set('__STATIC__', 'static')

// configure a development server for use in non-production modes,
config.devServer
.public('http://localhost:8080')
.host('localhost')
.port(8080)
.hotOnly(true)
.watchOptions({poll: 1000})
.https(false)
.headers({"Access-Control-Allow-Origin": ["*"]})

// DO have Webpack hash chunk filename
config.output
.chunkFilename("[id].js")
},

devServer: {
writeToDisk: true
}
};

关于django - Graphite 烯 django 端点是否同时需要 X-Csrftoken 和 CsrfCookie?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60533674/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com