Django/Graphene/Apollo/Django网页包加载程序/Vue:CORS/CSRF不工作?

Django/Graphene/Apollo/Django网页包加载程序/Vue:CORS/CSRF不工作?,django,vue.js,csrf,apollo,Django,Vue.js,Csrf,Apollo,我正在做一个项目,使用Django作为后端,Vue作为前端,并尝试实现Apollo/Graphene/GraphQL作为数据传输层。 大部分都能工作,但我不了解CORS/CSRF设置 (在这里做了很多研究,)和 有人知道如何通过CSRF令牌解决graphql/graphene API的安全问题吗?在django日志终端上,我得到: Forbidden (CSRF token missing or incorrect.): /graphql/ …在Vue/Js控制台上,我看到 Cross-Ori

我正在做一个项目,使用Django作为后端,Vue作为前端,并尝试实现Apollo/Graphene/GraphQL作为数据传输层。 大部分都能工作,但我不了解CORS/CSRF设置

(在这里做了很多研究,)和

有人知道如何通过CSRF令牌解决graphql/graphene API的安全问题吗?在django日志终端上,我得到:

Forbidden (CSRF token missing or incorrect.): /graphql/
…在Vue/Js控制台上,我看到

Cross-Origin Request Blocked: The Same Origin Policy disallows 
reading the remote resource at http://localhost:8080/sockjs-node/
info?t=1558447812102. 
您可以看到(并且签出,它是开源的)这个项目

查询
query{menuItems{id,title,slug,disabled}}
在graphiql中运行良好

settings.py:


已安装的应用程序=[
# ...
“护卫舰”,
“rest_框架”,
“网页包加载程序”,
“石墨烯”,
]
中间件=[
“corsheaders.middleware.Corsmidlware”,新增
# ...
]
CORS_ORIGIN_ALLOW_ALL=DEBUG#(=True)
问题在于: *
纱线服务
正在运行 *
/manage.py runserver
正在运行,并通过网页包代理Vue前端开发服务器

vue.config.js:


module.exports = {
    // The base URL your application bundle will be deployed at
    publicPath: 'http://localhost:8080',

    // ...

    chainWebpack: config => {
        // ...
        config.devServer
            .public('http://localhost:8080')
// ...
vue-apollo.js:

const httpEndpoint = process.env.VUE_APP_GRAPHQL_HTTP || 'http://localhost:8000/graphql/'
编辑:如果我将
graphql/
api urlpath与
csrf\u export
包装在一起,它会工作:

urlpatterns=[#。。。
路径('graphql/',csrf_豁免(GraphQLView.as_视图(graphiql=True,schema=schema)),
]

但这是一个糟糕的想法(TM)安全性。我如何使用Vue with Django和webpack_loader将该令牌放入前端?

对于该请求,跳过CSRF检查可能没什么问题,但无法根据您提供的信息对其进行评估,所以让我解释一下为什么我们首先需要CSRF检查

创建CSRF是为了修复HTTP和web浏览器工作方式中存在的“漏洞”。该漏洞如下所示:任何网站都可以包含向您的网站提交数据的发件人,这样做时,Cookie将随用户提交的表单一起传递

这意味着第三方网站可以欺骗您的用户在您的网站上执行某些操作。为了防止这种情况,我们创建了CSRF令牌的概念。简单地说:当第三方网站欺骗您提交任何可能对用户有害的操作时,您网站上负责执行该操作的任何表单都必须包含CSRF令牌field位于为此操作提交的所有数据旁边。相同的CSRF令牌需要存在于用户会话或cookie中。提交表单时,将比较这两个令牌,如果它们不匹配或其中任何一个不存在,表单将被拒绝

这将保护第三方网站提交的任何表单,因为其他网站无法读取来自您网站的cookie,即使这些cookie与来自此类网站的请求一起传递。因此,该网站无法在表单数据中设置匹配令牌

也就是说,当您不使用cookie保留用户会话时,此问题不存在。当您的前端位于单独的域上时,此问题也不存在,因为来自前端的所有请求都将具有带有域名的
头。因此,如果其中任何一种情况都是这样,您可以相应地禁用CSRF检查:

  • 当用户会话或用户身份验证不使用cookie时(例如,如果您纯粹依赖于通过头传递的JWT),您可以对所有不使用cookie的视图完全禁用CSRF
  • 当您的前端位于CORS允许连接到您的网站的单独域(或子域)上时,请使用
    CSRF\u TRUSTED\u ORIGINS
    将其列入白名单

小提示:安装的应用程序的顺序很重要。因此,也许可以尝试混淆视听,我相信这不会是一个解决方案,但你永远也不能太确定。“有人知道如何解决这个问题吗?”解决什么?你不清楚你遇到了什么实际问题。“原因是IMHO服务器由于CORS设置不正确而拒绝向外部提供数据。您会收到指示“CORS设置不正确”的确切错误消息吗?必须做些什么才能尝试修复该错误?”但我真的放弃了。”您放弃了解决问题的实际原因?现在您正在寻找解决方法?或者什么?“因此,主要问题可能是:如何将CSRF令牌集成到graphql api请求中?”这与CORS问题有什么关系?解决这一问题的更好方法是从一个域/端口为所有内容提供服务,并使用前端代理将内容路由到两台服务器(视情况而定)。我推荐Traefik解决这一问题。(为了补充我昨天的评论,如果您尝试使用非标准网络进行AJAX或WS请求,您可能会遇到公司/移动防火墙的麻烦。如果可以,请坚持使用80/443,除非您知道您的用户群不会有问题)@nerdoc…我使用Axios和vue.js从后端收集所需的数据。在这种情况下,有很多帖子都是关于如何允许传递CSRF令牌的,因此Django支持您的调用,但或多或少您只需设置一个全局默认值即可:
Axios.defaults.xsrfHeaderName=“X-CSRFToken”
然后
axios.defaults.xsrfCookieName='csrftoken'