I am trying to send a JSON POST request to my Django server.
It reports this error: Forbidden (CSRF token missing or incorrect.):
In my Django template, options.html
, I say this:
<script>const incomingToken = "{{ csrf_token }}";</script>
And this:
<input type="hidden" name="csrf-token" id="csrf-token" value="{{ csrf_token }}" />
Then in my JavaScript file that runs in the client I say:
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)
});
Both incomingToken
and document.getElementById("csrf-token").value
report the same value. So I know I'm getting the correct string for the CSRF token.
How can this be? What am I doing wrong?
For reference, here is what I see in 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'
})
});
Instead of running a function to retrieve the value from a cookie, I simply insert the value Django embeds using {{ csrf_token }}
. I also tried pasting the code from the top answer in this thread, including function getCookie(name)
. Nothing. Client still says POST http://127.0.0.1:8000/ 403 (Forbidden)
, server still cries with the same Forbidden (CSRF token missing or incorrect.)
error.
Suggestions please!
Update:
So I tried a function from Django's CSRF protection docs page that reads:
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;
}
For whatever reason, this function returns a different value when I run getCookie("csrftoken")
-- a value that is different from that of what is embedded by {{ csrf_token }}
. Dunno what to make of that. Neither one works when inserting it into "X-CSRFToken"
in my headers.