【问题标题】:Django backend, React frontend and CSRF PostDjango 后端、React 前端和 CSRF Post
【发布时间】:2019-03-02 07:47:43
【问题描述】:

在我的场景中,我在我的反应前端 (http://localhost:3000/submit) 中使用一个表单来发布到我的网址 http://localhost:8000/api/submit/

但是,我收到了这样的回复:

“detail”:“CSRF 失败:CSRF 令牌丢失或不正确。”

我的班级视图是这样的:

from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser

class Submit(APIView):
    parser_classes = (MultiPartParser, FormParser)
    def post(self, request, *args, **kwargs):
        #custom post

我有两个问题:

  1. 如何装饰 dispatch() 以免除 csrf?
  2. 如何向我的前端提供 CSRF?

**

Risadinha 的解决方案:

**

import cookie from "react-cookies";

...

<input
 type="hidden"
 value={cookie.load("csrftoken")}
 name="csrfmiddlewaretoken"
/>

【问题讨论】:

标签: django reactjs csrf


【解决方案1】:

您需要将 cookie 和标头设置为在初始调用期间传输的 CSRF 令牌,以加载反应页面。

基本上,您需要读取从 Django 服务器传输的 cookie“csrftoken”的值,并将其设置为 react 应用程序中所有后 AJAX 请求的标头“X-CSRFTOKEN”的值。一般情况下最好完成(例如 index.js)。

在 React 中使用 axios(我们正在使用 graphql)客户端的示例:

import axios from "axios";
import cookie from "react-cookies";

axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";

your_client.setHeaders({"X-CSRFTOKEN": cookie.load("csrftoken")});

如果没有 ajax,将 cookie 的值添加到这样的表单中 - 如果您不能使用模板标签 {% csrf_token %}(在反应表单中):

<input type="hidden" name="csrfmiddlewaretoken" value="{value-of-the-cookie}" /> 

文档:https://docs.djangoproject.com/en/3.1/ref/csrf/

【讨论】:

  • 我应该把这些代码放在哪里?什么是“your_client”?
  • 这取决于你如何在你的 react 应用中实现 AJAX 请求。我们正在使用 axios,因此我们有一个客户端实例。由于这是应该应用于所有 ajax(post)请求的东西,因此在 index.js 等代码的一般部分中设置它是可行的。
  • 但在这种情况下,我没有使用 AJAX。我有一个表单并将输入数据直接发布到我的 django 后端。我不知道如何生成 CSRF 令牌以插入到 或如何从 django 中检索它并将输入值设置为它。
【解决方案2】:

这似乎有点 hacky,但您可以使用 django.middleware.csrf.get_token() 方法在视图中获取 csrf 令牌。所以我会做出这样的看法:

from django.http import JsonResponse

def get_csrf(request):
    csrf_token = django.middleware.csrf.get_token()
    return JsonResponse({'csrf_token':csrf_token})

当然,您希望保护此请求,以便任何人都无法获取令牌。无论如何,这似乎违背了它的目的......

【讨论】:

  • 任何不是 CSRF 豁免的请求都已经在标头和 cookie 中包含令牌。再次发出请求以获取已包含两次的数据是没有任何意义的。
  • 我认为这可以帮助使用 create-react-app 之类的东西并且前端与后端分开托管的人,因为如果他们提出的请求包含令牌,他们可以使用 django 会话来存储用户数据
猜你喜欢
  • 2011-12-26
  • 2018-02-06
  • 2019-10-22
  • 2017-03-04
  • 1970-01-01
  • 2015-10-15
  • 2016-01-21
  • 1970-01-01
  • 2021-04-01
相关资源
最近更新 更多