簡體   English   中英

盡管正確發送令牌,Django 服務器仍報告“禁止(CSRF 令牌丟失或不正確。)”?

[英]Django server reporting "Forbidden (CSRF token missing or incorrect.)" despite sending token correctly?

我正在嘗試向我的 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 令牌的正確字符串。

怎么會這樣? 我究竟做錯了什么?

作為參考,這是我在另一個主題中看到的內容

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 嵌入的值。 我還嘗試粘貼此線程中頂級答案中的代碼,包括function getCookie(name) 沒有。 客戶端仍然說POST http://127.0.0.1:8000/ 403 (Forbidden) ,服務器仍然以相同的Forbidden (CSRF token missing or incorrect.)錯誤哭泣。

請提出建議!

更新:

所以我嘗試了Django 的 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"時,兩者都"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)
        });

它奏效了!

不同之處在於在fetch參數中使用了new Request()對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM