We are facing a bit of an issue with CSRF tokens in our application. Our Django application is embedded in Shopify. I know browsers are getting a bit strict on the third-party cookies but haven’t been able to find a solution to setting the CSRF token it the browser.
For now, we are forced to comment out 'django.middleware.csrf.CsrfViewMiddleware',
in settings.py, which I don’t believe is the correct way to go.
In my settings.py:
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
ALLOWED_HOSTS = [
"admin.shopify.com",
"www.mydomain.com",
]
CSRF_TRUSTED_ORIGINS = [
"admin.shopify.com",
"www.mydomain.com",
]
...
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
...
# Session settings
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_COOKIE_NAME = 'sessionid'
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = None
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_AGE = 1209600
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_SAVE_EVERY_REQUEST = True
CSRF_COOKIE_NAME = 'csrftoken'
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = None
Then, in my JavaScript I have the following code to set the CSRF cookie:
// CSRF Token
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
let csrftoken = getCookie('csrftoken');
console.log('CSRF Token:', csrftoken);
function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
However, console.log('CSRF Token:', csrftoken);
outputs null
.
This is only happening when we browse the site through Shopify. If we browser it natively in the browser then the cookie is set as expected.