bla*_*sun 4 django graphql graphene-python vue-apollo graphene-django
使用:
\n\n我正在使用 Django、GraphQL 和 Vue-Apollo 测试单页 vue app\xc2\xb4s。
\n\n如果我csrf_exempt在我的视图中使用,一切都会在前端运行。
urlpatterns = [\n<...>\n path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True))),\n<...>\nRun Code Online (Sandbox Code Playgroud)\n\n现在我想要 CSRF 保护我的请求。\n在理解 CSRF 保护的过程中,我认为 DjangoGraphQLView所需要的只是接收X-Csrftoken请求标头中的“值”。所以我专注于csrf以不同的方式发送值......通过像这样的单一视图
path(\'csrf/\', views.csrf),\npath("graphql", GraphQLView.as_view(graphiql=True)),\nRun Code Online (Sandbox Code Playgroud)\n\n或者通过确保 cookieensure_csrf_cookie
然后在我的ApolloClienti 中获取这些 Value 并将其与请求 Header 一起发回。
这是当我从 Django-Vue 页面发送 GraphQL 请求时 Django 打印的内容。
\n\nForbidden (CSRF token missing or incorrect.): /graphql\nRun Code Online (Sandbox Code Playgroud)\n\n并行我总是测试graphiql IDE这些请求仍然有效。我每次都会打印info.context.headers查询解析器的值。
{\'Content-Length\': \'400\', \'Content-Type\': \'application/json\',\n\'Host\': \'localhost:7000\', \'Connection\': \'keep-alive\',\n\'Pragma\': \'no-cache\', \'Cache-Control\': \'no-cache\', \n\'Accept\': \'application/json\', \'Sec-Fetch-Dest\': \'empty\', \'X-Csrftoken\': \'dvMXuYfAXowxRGtwSVYQmpNcpGrLSR7RuUnc4IbIarjljxACtaozy3Jgp3YOkMGz\',\n\'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\',\n\'Origin\': \'http://localhost:7000\',\n\'Sec-Fetch-Site\': \'same-origin\', \'Sec-Fetch-Mode\': \'cors\',\n\'Referer\': \'http://localhost:7000/graphql\', \'Accept-Encoding\': \'gzip, deflate, br\', \'Accept-Language\': \'en-US,en;q=0.9,de;q=0.8\',\n\'Cookie\': \'sessionid=jqjvjfvg4sjmp7nkeunebqos8c7onhiz; csrftoken=dvMXuYfAXowxRGtwSVYQmpNcpGrLSR7RuUnc4IbIarjljxACtaozy3Jgp3YOkMGz\'}\nRun Code Online (Sandbox Code Playgroud)\n\n我认识到他们GraphQLView IDE总是将“ X-Csrftoken和”Cookie:..csrftoken.也放在请求中。GraphQLView IDE如果在发送请求之前删除 a 的 csrftoken-cookie ,我会得到这个
Forbidden (CSRF cookie not set.): /graphql\nRun Code Online (Sandbox Code Playgroud)\n\nIDE 显示一个长的红色报告
\n\n.... CSRF verification failed. Request aborted.</p>\\n\\n\\n \n<p>You are seeing this message because this site requires a CSRF cookie when submitting forms.\nThis cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p>\\n\nRun Code Online (Sandbox Code Playgroud)\n\nIDE 的信息表明\xc2\xb4s 请求需要 CSRF cookie。但到目前为止在论坛 Doc\xc2\xb4s 中阅读的所有内容都与价值本身更相关。这意味着您所需要的只是在标头中发送 csrf 值X-Csrftoken,然后视图就会发挥作用。
问题
\n\n因此我的问题是:
\n\n我是否必须在 my 中同时设置X-Csrftoken和 the才能对我的 django 发出请求?Cookie:..csrftokenApolloClientGraphQLView
或者是否也可以简单地仅发送X-Csrftoken不带 a 的内容csrf-cookie,反之亦然?
经过很长时间和暂停来关注这个问题,我再次尝试并找到了解决方案。
\n设置
\n假定
\n*vue.js当我在 Django 中写入文件时,Webpack DevServer 将热重载STATICFILES_DIRS。Django 将从那里获取文件。工作正常问题回顾
\n重新审视我的问题后,我注意到我有两个问题。其中之一是浏览器由于 CORS 拒绝了 graphQL 请求。第二个是 CSRF 代币。
\n解决方案
\n为了修复 CORS 问题,我注意到我uri的 Apollo 客户端与我的 Django 开发服务器不同。相反,http://127.0.0.1:7000/graphql它被设置为http://localhost:7000/graphql. 我还设置了credentials(参见 vue-apollo.js)
为了修复 CSRF 我做了 3 件事
\n{% csrf_token %}带有 Vue/GraphQL 客户端应用程序挂钩的 HTML。以便我们稍后可以获取它。js-cookie以获取 CookieX-CSRFTokenin设置标头vue-apollo.js\n\nvue-apollo.js
\n
import Vue from 'vue'\n// import path for the new Apollo Client 3 and Vue-Apollo\nimport { ApolloClient, InMemoryCache } from '@apollo/client/core';\nimport VueApollo from 'vue-apollo'\nimport Cookies from 'js-cookie'\n\n \n// Create the apollo client\nconst apolloClient = new ApolloClient({\n // -------------------\n // # Required Fields #\n // -------------------\n // URI - GraphQL Endpoint\n uri: 'http://127.0.0.1:7000/graphql',\n // Cache\n cache: new InMemoryCache(),\n\n // -------------------\n // # Optional Fields #\n // -------------------\n // DevBrowserConsole\n connectToDevTools: true,\n // Else\n credentials: 'same-origin',\n headers: {\n 'X-CSRFToken': Cookies.get('csrftoken')\n }\n});\n \n// create Vue-Apollo Instance\nconst apolloProvider = new VueApollo({\n defaultClient: apolloClient,\n})\n \n// Install the vue plugin\nVue.use(VueApollo)\n \nexport default apolloProvider\nRun Code Online (Sandbox Code Playgroud)\n\n\nVue.config.js
\n
const BundleTracker = require("webpack-bundle-tracker");\n\n// hook your apps\nconst pages = {\n 'page_1': {\n entry: './src/page_1.js',\n chunks: ['chunk-vendors']\n },\n 'page_2': {\n entry: './src/page_2.js',\n chunks: ['chunk-vendors']\n },\n}\n\nmodule.exports = {\n pages: pages,\n filenameHashing: false,\n productionSourceMap: false,\n\n // puplicPath: \n // Tells Django where do find the bundle.\n publicPath: '/static/',\n\n // outputDir:\n // The directory where the production build files will be generated - STATICFILES_DIRS\n outputDir: '../dev_static/vue_bundle',\n \n \n chainWebpack: config => {\n\n config.optimization\n .splitChunks({\n cacheGroups: {\n vendor: {\n test: /[\\\\/]node_modules[\\\\/]/,\n name: "chunk-vendors",\n chunks: "all",\n priority: 1\n },\n },\n });\n\n\n // Don\xc2\xb4t create Templates because we using Django Templates\n Object.keys(pages).forEach(page => {\n config.plugins.delete(`html-${page}`);\n config.plugins.delete(`preload-${page}`);\n config.plugins.delete(`prefetch-${page}`);\n })\n\n // create webpack-stats.json. \n // This file will describe the bundles produced by this build process.\n // used eventually by django-webpack-loader\n config\n .plugin('BundleTracker')\n .use(BundleTracker, [{filename: '/webpack-stats.json'}]);\n\n\n // added to use ApolloQuery Tag (Apollo Components) see vue-apollo documentation\n config.module\n .rule('vue')\n .use('vue-loader')\n .loader('vue-loader')\n .tap(options => {\n options.transpileOptions = {\n transforms: {\n dangerousTaggedTemplateString: true,\n },\n }\n return options\n })\n \n // This will allows us to reference paths to static \n // files within our Vue component as <img src="~__STATIC__/logo.png">\n config.resolve.alias\n .set('__STATIC__', 'static')\n\n // configure a development server for use in non-production modes,\n config.devServer\n .public('http://localhost:8080')\n .host('localhost')\n .port(8080)\n .hotOnly(true)\n .watchOptions({poll: 1000})\n .https(false)\n .headers({"Access-Control-Allow-Origin": ["*"]})\n \n // DO have Webpack hash chunk filename\n config.output\n .chunkFilename("[id].js")\n },\n\n devServer: {\n writeToDisk: true\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2802 次 |
| 最近记录: |