403 石墨烯-django。不要使用 csrf_exempt

Kou*_*aki 8 django graphql

我用graphene-django。创建一个应用程序,GraphiQL对于登录和其他功能运行良好。但是当我使用时Insomnia,我收到403 Forbidden错误。

我参考了这个文档, https://github.com/howtographql/howtographql/blob/master/content/backend/graphql-python/4-authentication.md

我尝试过:

  1. 使用csrf_exempt; 它工作得很好,但我当然不会使用它。
  2. 使用django-cors-headers; 它不好用。

我该如何解决这个403错误?

edo*_*ron 5

我不推荐@yestema 的第二种方法来解决您面临的问题。

\n\n

避免使用 GET查询 GraphQL 端点的方法

\n\n

如果想要实现这一解决方法并且还使用 Graphql for mutations,那么它看起来像是糟糕的设计。

\n\n

已经建立了一项标准,即GET请求不得更改服务器或数据库的状态,并且mutations在大多数情况下,用于更改一个或另一个的状态(可能只是数据库,因为您的应用程序应该是无状态的) )。

\n\n

请注意,您还可以使用query方法来更改后端的状态,但是,这又违反了既定标准,如grapqhl 文档中所述:

\n\n
\n

[...] 在 REST 中,任何请求最终都可能对服务器造成一些副作用,但按照惯例,建议不要使用 GET 请求来修改数据。GraphQL 类似 - 从技术上讲,任何查询都可以实现以引起数据写入。然而,建立一个约定是有用的,即任何导致写入的操作都应该通过突变显式发送。

\n
\n\n

什么时候使用csrf_exempt装饰器是安全的?

\n\n

为了给那些想知道摆脱默认 CSRF 检查有多糟糕的人提供提示,这里是我的两分钱解释。

\n\n

当浏览器自动发送身份验证参数时,服务就会受到 CSRF 攻击,这是基于会话的默认 Django 身份验证系统的情况。

\n\n

如果您仅将 Django 应用程序用作 API 后端,则您很可能依赖其他身份验证机制,例如DRF 的 TokenAuthentication或某种JWT 实现

\n\n

基本上,这些身份验证系统不受 CSRF 攻击,因为如果恶意网站想要代表您的用户 \xe2\x80\x94 访问您的服务器(这就是 CSRF 的全部内容 \xe2\x80\x94),它就不会\'无法设置Authorization服务器期望的 HTTP 标头来实际验证请求(前提是您将令牌安全地存储在只能由前端应用程序域访问的 cookie 中......)。

\n\n
\n\n

太长了;博士

\n\n

继续发送带有请求的 GraphQL 查询POST,这是最佳实践。

\n\n

如果您的 GraphQL 端点只能由经过身份验证的用户访问,并且您的身份验证系统不依赖于 Django 会话,则可以免除您的端点的 CSRF 检查。

\n\n

但是,如果您使用Django的默认身份验证系统\xe2\x80\x94,即sessionid存储在cookie中,那么您必须强制执行csrf验证。\n此时,正如前面的答案所述,您唯一的机会是在 HTTP 请求中添加标头,并为其提供先前向服务器发出的请求自动设置X-CSRFToken的 cookie 值。csrftoken

\n\n
\n\n

我最初在GitHub上发布了这个答案,但认为它在这里也可能有用。

\n


Exi*_*ang 1

如果您想将 CSRF 中间件与 Graphene 一起使用,那么您需要在请求标头的 cookie 中设置 CSRF 令牌。

我没有 Insomnia 的经验,但我确信它可以让您自定义请求标头,就像 Apollo 链接一样。