django/graphene/apollo/django-webpack-loader/vue:CORS/CSRF不同



我正在使用django作为后端,作为前端进行vue,并尝试实现Apollo/Graphene/GraphQl作为数据传输层。大部分都有效,但我不围绕CORS/CSRF设置。

(这里确实有很多研究。在这里,这里和这里。

有人知道如何通过CSRF令牌解决graphql/chuperene 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. 

您可以在这里看到此项目。

http://localhost:8000,http://localhost:8000/admin和http://http://localhost:8000/工作得很好。查询query{menuItems{id, title, slug, disabled}}在GraphiQl中运行良好。

settings.py:


INSTALLED_APPS = [
    # ...
    'corsheaders',
    'rest_framework',
    'webpack_loader',
    'graphene_django',
]
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # new
    # ...
]
CORS_ORIGIN_ALLOW_ALL = DEBUG    # (=True)

问题在这里:* yarn serve在http://localhost上运行:8080* ./manage.py runserver在http://localhost:8000上运行,并通过webpack vue frontend dev服务器进行代理。

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/'

编辑:如果我用 csrf_exempt包裹 graphql/ api urlpath,则有效:

urlpatterns = [ # ...
    path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))),
]

,但这是Badidea(TM(安全性。我如何使用django和webpack_loader使用VUE将该令牌进入前端?

可能会跳过CSRF检查该请求是可以的,但是很难从您提供的信息中进行评估,因此让我解释一下为什么我们首先需要CSRF检查。

CSRF的创建是为了修复"洞"。这在HTTP和Web浏览器的工作方式中都存在。这个漏洞如下:任何网站都可以包含将数据提交给您网站的表格,并且在这样做时,将与用户提交的表格一起传递cookie。

这意味着第三方网站可以诱使您的用户在您的网站上执行一些操作。为了防止这种情况,创建了CSRF令牌的想法。简单地说:您网站上的任何表格负责在第三方网站欺骗它提交时对用户有害的任何操作都必须包含一个CSRF代币字段。需要在用户会话或cookie中存在相同的CSRF令牌。提交表格时,将比较这些两个令牌,如果它们不匹配或不存在任何两个令牌,则表格将被拒绝。

这保护了第三方网站要提交的任何表格,因为您网站上的cookie也无法由其他网站读取,即使它们与该网站的请求一起通过。然后,该网站不可能在表单数据中设置匹配令牌。

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

  • 当不为用户会话或用户身份验证使用cookie时(例如,如果您纯粹依靠标题传递的JWT(,则可以完全禁用CSRF,以完全禁用所有不使用cookie的视图。
  • 当您的前端位于单独的域(或子域(上时,CORS允许连接到您的网站,请使用CSRF_TRUSTED_ORIGINS将其白色。

最新更新