【问题标题】:Django server reporting "Forbidden (CSRF token missing or incorrect.)" despite sending token correctly?尽管正确发送令牌,Django服务器仍报告“禁止(CSRF令牌丢失或不正确。)”?
【发布时间】:2021-01-03 17:49:02
【问题描述】:

我正在尝试向我的 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)
        });

incomingTokendocument.getElementById("csrf-token").value 都报告相同的值。所以我知道我得到了正确的 CSRF 令牌字符串。

这怎么可能?我做错了什么?

作为参考,这是我在another thread on the subject看到的:

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 中检索值,而是简单地使用 {{ csrf_token }} 插入 Django 嵌入的值。我还尝试从the top answer in this thread 粘贴代码,包括function getCookie(name)。没有。客户端仍然说POST http://127.0.0.1:8000/ 403 (Forbidden),服务器仍然以同样的Forbidden (CSRF token missing or incorrect.) 错误哭泣。

请提出建议!

更新:

所以我尝试了Django's CSRF protection docs page 中的一个函数,内容如下:

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" 时,两者都不起作用。

【问题讨论】:

    标签: javascript django csrf


    【解决方案1】:

    我找到了问题的解决方案。

    当我忽略了我在 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)
            });
    

    它成功了!

    不同之处在于在fetch 参数中使用new Request() 对象。

    【讨论】:

      猜你喜欢
      • 2019-11-24
      • 2021-01-08
      • 2021-07-14
      • 2015-10-15
      • 2020-12-24
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      相关资源
      最近更新 更多