Got migrating legacy project from Python 2.7 & Django 1.9 to Python 3.10 & Django 4.1.
There is also a bunch of JavaScript code which I only have a general idea of.
Stuck struggling with 403 Code with POST Request from url to another due to important CSRF protection:
Help
Reason given for failure:
Origin checking failed - null does not match any trusted origins.In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django’s CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies. The view function passes a request to the template’s render method. In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL. If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, aswell as those that accept the POST data. The form has a valid CSRF token. After logging in in another browser tab or hitting the back button after a login, you may need to reload the page with the form, because the token is rotated after a login.
You’re seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.
Looked through the SO and found no close solution.
As far as it was discovered, JavaScript generates JSON Response as it should, namely:
{"oneParameter": [[18, 0.1], [19, 0.5], [20, 1.0], [21, 3.0], [22, 4.0], [23, 6.0]], "anotherParameter": [[33, -3], [34, -5], [35, -10], [36, -15], [37, -20], [38, -25], [39, -30], [40, -35], [41, -40], [42, -45], [43, -50]]}
However, this JSON has no place to store requisites of the csrfmiddlewaretoken.
Upon reference to the documentation https://docs.djangoproject.com/en/4.1/ref/csrf/#rejected-requests:
New in Django 4.0: Origin checking was added, as described above.
it seems that is where the bug is concealed.
Got the following JS-code:
function markFunction() {
if (subject_select.value) {
$.ajax({
type: 'POST',
url: '/autocomplete-one-parameter-another-parameter/',
timeout: 3000,
async: true,
tryCount: 0,
retryLimit: 3,
dataType: 'json',
data: {
// Modification Required Here, I suppose >>
id_subject: subject_select.value,
csrfmiddlewaretoken: getCookie('csrftoken')
},
success: function (data) {
if (data) {
var anPt = document.getElementById('id_anotherParameter');
removeOptions(anPt);
var oneParameters = document.getElementById('id_oneParameters');
removeOptions(oneParameters);
var anPtsLength = data['anotherParameters'].length;
console.log("anPtsLength", anPtsLength);
var oneParametersLength = data['oneParameters'].length;
for (var i = 0; i < anPtsLength; i++) {
temp = document.createElement("option");
temp.value = data['anotherParameters'][i][0];
temp.text = data['anotherParameters'][i][1];
anPt.add(temp, null);
}
for (var i = 0; i < oneParametersLength; i++) {
temp = document.createElement("option");
temp.value = data['oneParameters'][i][0];
temp.text = data['oneParameters'][i][1];
oneParameters.add(temp, null);
}
anPt.removeAttribute('disabled');
oneParameters.removeAttribute('disabled');
}
},
error: function(xhr, textStatus, errorThrown) {
}
});
} else {
var anPt = document.getElementById('id_anotherParameter');
removeOptions(anPt);
anPt.setAttribute('disabled', 'disabled');
var oneParameters = document.getElementById('id_oneParameters');
removeOptions(oneParameters);
oneParameters.setAttribute('disabled', 'disabled');
}
}
Upon some research, has either of two options how to integrate Origin header:
const csrftoken = getCookie('csrftoken');
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
jqXHR.setRequestHeader('X-CSRFToken', csrftoken);
});
or that from Documentation:
const request = new Request(
'/autocomplete-one-parameter-another-parameter/',
{
method: 'POST',
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin' // Do not send CSRF token to another domain.
}
);
fetch(request).then(function(response) {
// ... << Don't understand how to integrate this to the JS above
});
Please can anyone explain which of the options shall be chosen and help with integrating these two pieces of chain?