I'm developing two separate django (version 3.1) projects. I keep getting a "403: CSRF cookie not set" error and have no idea what the problem is.
- Project 1 is running on an Apache server & takes POST requests containing JSON data & sends back a JSON response.
- Project 2, running on localhost, sends the POST via Javascript
XMLHttpRequest()
function to Project 1.
This question seems to be having the same problem as me, but I'm trying to send info between different URL's (more specifically, POST from localhost:8000, eventually url.com, to engine.url.com) and I don't think that user's solution will work for me.
I've tried using the @csrf_exempt
decorator on Project 1 views.py
, and it works just fine. However, personally identifying information might be sent between the two, so I want to make sure things are secure. A csrf cookie is best practice if I'm not mistaken, so I have the decorator @ensure_csrf_cookie
before my view.
I've tried everything I could find online to fix the problem. In Project 1 settings.py
, I've included 'corsheaders'
in my INSTALLED_APPS
, 'django.middleware.csrf.CsrfViewMiddleware'
in MIDDLEWARE
and have the following code at the end of the file:
CSRF_COOKIE_SECURE = False
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = False
CORS_ALLOWED_ORIGINS = [
'http://project.com',
'https://project.com',
'http://engine.project.com',
'https://engine.project.com',
'localhost:8000',
'http://localhost:8000',
'127.0.0.1',
'http://127.0.0.1',
]
CORS_ALLOW_HEADERS = [
'X-CSRFToken',
'x-csrftoken',
'X-CSRFTOKEN',
'content-type',
]
I include a {% csrf_token %}
in the Project 2 template, but the actual POST request is coming from the Javascript. Pertinent excerpt from the Javascript static file below:
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;
}
function getPaymentDates(jsonData) {
const csrftoken = getCookie('csrftoken');
jsonData.csrfmiddlewaretoken = csrftoken;
var sentJsonString = JSON.stringify(jsonData);
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://engine.project.com/app/", false);
xhr.setRequestHeader('X-CSRFToken', csrftoken);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(sentJsonString);
// xhr response should be a json string
return xhr.response;
}
getCookie()
is lifted straight from the csrf django documentation.
After testing in the console, I know a cookie is obtained, but I get a 403 error before the app can do anything with the data. Again, if I use @csrf_exempt
then the app works just fine, but if that makes the data vulnerable to malintent, then I want to prevent that.
Am I redundantly calling for a csrf cookie which causes an error? I'm stumped and somewhat new to web development. Happy to provide more code if that aids in answering this question.