首页 > 解决方案 > CSRF 验证失败。使用 Python Django 后端和 React,Axios(使用 POST)前端

问题描述

我正在关注本教程https://www.valentinog.com/blog/drf/并成功完成了它。我正在尝试向本教程添加 POST 功能。问题是我无法使用 Axios ajax 框架添加 POST 命令以将 csrf 值发送到服务器。

我已经获得了 cookie 上的 csrf,并将其存储在“csrfmiddlewaretoken”变量中,然后是一条以 json 格式嵌入到 axios 函数的测试消息,但它不起作用导致 403 错误。我将@ensure_csrf_cookie 装饰器添加到views.py 但仍然是同样的错误。

在views.py 上使用@csrf_exempt 装饰器可以解决这个问题,但是我想使用csrf 来保证安全。

我在 venv 上使用 Django 版本 3.0.8

csrftoken.js

import React from "react";
function getCookie(name) {
  var cookieValue = null;
  if (document.cookie && document.cookie !== "") {
    var cookies = document.cookie.split(";");
    for (var i = 0; i < cookies.length; i++) {
      var cookie = cookies[i].trim();
      if (cookie.substring(0, name.length + 1) === name + "=") {
        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
        break;
      }
    }
  }
  return cookieValue;
}
var csrftoken = getCookie("csrftoken");

const CSRFToken = () => {
  return <input type="hidden" name="csrfmiddlewaretoken" value={csrftoken} />;
};
export default CSRFToken;

应用程序.js

...
import axios from "axios";
import CSRFToken from "./csrftoken";
...
sendPost() {
var jsonPost = {
      csrfmiddlewaretoken: document.getElementsByTagName("input")[
        "csrfmiddlewaretoken"
      ].value,
      transmitter: "This is houston Do you hear me Copy ",
    };
   axios({
      method: "post",
      url: "/api/sendpost/",
      data: jsonPost,
    })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
  }
...
 render() {
    return (
      <ul>
        <CSRFToken />
        {this.state.data.map((contact) => {
          return (
            <div>
              <li key={contact.id}>
                {contact.name} - {contact.email}
              </li>
              <button onClick={() => this.sendPost()}>
                Send A Post Message
              </button>
            </div>
          );
        })}
      </ul>
    );
  }

引导应用程序views.py

from django.views.decorators.csrf import csrf_exempt,ensure_csrf_cookie
from django.http import JsonResponse
#@csrf_exempt
@ensure_csrf_cookie
def receivePost(request):
    print(request.POST)
    data = {
        "receiver":"Received Houston"
    }
    return JsonResponse(data)

设置.py

...
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.authentication.TokenAuthentication',
    ),
}
...

网址.py

from django.urls import path
from . import views

urlpatterns = [
    path('api/lead/', views.LeadListCreate.as_view() ),
    path('api/sendpost/', views.receivePost ),
]

编辑:似乎 print(request.POST) 返回一个空的 Querydict {} 即使在views.py上启用@csrf_exempt

标签: javascriptpythondjangoreactjsaxios

解决方案


推荐阅读