javascript - 尽管正确发送令牌,Django服务器仍报告“禁止(CSRF令牌丢失或不正确。)”?
问题描述
我正在尝试向我的 Django 服务器发送 JSON POST 请求。
它报告此错误:Forbidden (CSRF token missing or incorrect.):
在我的 Django 模板中options.html
,我这样说:
<script>const incomingToken = "{{ csrf_token }}";</script>
和这个:
<input type="hidden" name="csrf-token" id="csrf-token" value="{{ csrf_token }}" />
然后在客户端运行的 JavaScript 文件中,我说:
const serverUrl = "http://127.0.0.1:8000/"
const headers = new Headers({
'Accept': 'application/json',
// 'X-CSRFToken': getCookie("CSRF-TOKEN")
"X-CSRFToken": document.getElementById("csrf-token").value
})
fetch(serverUrl, {
method: "POST",
headers: {
headers
},
mode: "same-origin",
body: JSON.stringify(editorState.expirationDate, editorState.contracts, editorState.theta) // FIXME: server goes "Forbidden (CSRF token missing or incorrect.)" and 403's
}).then(response => {
console.log(incomingToken)
console.log(document.getElementById("csrf-token").value)
console.log(response)
}).catch(err => {
console.log(err)
});
两者都incomingToken
报告document.getElementById("csrf-token").value
相同的值。所以我知道我得到了 CSRF 令牌的正确字符串。
怎么会这样?我究竟做错了什么?
作为参考,这是我在关于该主题的另一个线程中看到的内容:
const csrfToken = getCookie('CSRF-TOKEN');
const headers = new Headers({
'Content-Type': 'x-www-form-urlencoded',
'X-CSRF-TOKEN': csrfToken // I substitute "csrfToken" with my code's "incomingToken" value
});
return this.fetcher(url, {
method: 'POST',
headers,
credentials: 'include',
body: JSON.stringify({
email: 'test@example.com',
password: 'password'
})
});
我没有运行一个函数来从 cookie 中检索值,而是简单地插入 Django 嵌入的值,使用{{ csrf_token }}
. 我还尝试粘贴此线程中最佳答案中的代码,包括function getCookie(name)
. 没有什么。客户仍然说,服务器仍然因同样的错误而POST http://127.0.0.1:8000/ 403 (Forbidden)
哭泣。Forbidden (CSRF token missing or incorrect.)
请提出建议!
更新:
所以我尝试了Django 的 CSRF 保护文档页面中的一个函数,内容如下:
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
无论出于何种原因,这个函数在我运行时返回一个不同的值getCookie("csrftoken")
——这个值与嵌入的值不同{{ csrf_token }}
。不知道该怎么做。将其插入"X-CSRFToken"
我的标题时,两者都不起作用。
解决方案
我找到了问题的解决方案。
当我忽略了我在 StackOverflow 上找到的大部分内容并选择只使用 Django 文档时,解决方案就出现了。
我在我的 OP 中编写了我的代码 - 看看它是如何制作标题的new Headers()
?以及如何fetch
作为serverUrl
第一个参数插入?
好吧,我将其更改为如下所示:
const serverUrl = "http://127.0.0.1:8000/"
const request = new Request(serverUrl, { headers: { 'X-CSRFToken': getCookie("csrftoken") } })
fetch(request, {
method: "POST",
mode: "same-origin",
body: JSON.stringify(editorState.expirationDate, editorState.contracts, editorState.theta)
}).then(response => {
console.log(response)
}).catch(err => {
console.log(err)
});
它奏效了!
不同之处在于在参数中使用new Request()
对象。fetch
推荐阅读
- python - 将 python 文件从当前位置运行到另一个位置?
- c - C:结合 while 和 if 语句
- gnome - 如何在 GNOME 中关闭工作区?
- python - 检索 column1 和 column2 中的所有数据
- android - 更新到 gradle 3.2.0 后,无法对来自电视模块的布局文件使用数据绑定
- python - 从字符串中提取字符并制作列表
- windows - Windows命令提示符命令复制文件?
- java - 在封闭类之外调用扫描仪对象时如何关闭它?
- r - R取消列表并分配元素位置
- jboss - 在 Jboss Wildfly 上使用“/”作为默认项目根目录