javascript - 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
解决方案
推荐阅读
- machine-learning - 如何使用八度 fminunc 函数优化 theta
- c++ - 为用户定义的文件名指定路径
- c# - C# 创建通用项列表以传递给采用基类的函数
- c# - 使用 dicom Leadtools 读取嵌套元素/序列
- c - 错误:*(int **,int,int,int)' 与 'int ()' 的间接级别不同,我该如何解决?
- google-sheets - 如何使用项目的数量排列列表以显示该订单的每个项目的行
- mysql - 使一列的总和成为特定值查询sql
- ruby-on-rails - Rails 5.2 CORS 被阻止
- python - 无法理解 SciPy.signal.spectrogram 输出
- bash - yq - 添加多行字符串