I'm trying to use an iframe of my django site in a different domain, however whenever I submit a form, It says the CSRF cookies is not set. This occurs in chrome and safari. I am running Django 3.1.0.
I've tried adding the following settings in my settings.py:
SESSION_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SECURE = True
X_FRAME_OPTIONS = 'ALLOWALL'
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CSRF_COOKIE_SECURE = False
CSRF_COOKIE_SAMESITE = None
CSRF_COOKIE_HTTPONLY = False
CSRF_TRUSTED_ORIGINS = [
'otherdomain.com',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
]
Further, I can confirm the csrf token is being set in the form using:
{% csrf_token %}
Lastly, I've also added the #xframe_options_exempt decorator to the form page.
Edit: I am also using the render method to display the form as recommended by the documentation.
Edit2: For some more context, this form functions fine when it is used in the host domain (not an iframe)
Unfortunately the csrf exempt decorator is not an option for me. I've tried clearing my cookies, though it does not solve my problem. Any help would be greatly appreciated!
This was solved by changing the value of CSRF_COOKIE_SAMESITE to 'None' instead of None. Apparently Chrome requires it to be an explicit string, not an empty value
Related
I have installed django-cors-headers and this is settings.py :
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS","").split()
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
and also :
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_CREDENTIALS = True
but i got this error in chrome consloe:
Access to XMLHttpRequest at 'https://event-alpha.mizbans.com/api/meetings/?memory=0' from origin 'https://alpha.mizbans.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I had a similar issue and it was all about CORS_ALLOW_ALL_ORIGINS. It turns out it doesn't work well with something else (sorry don't remember what anymore, maybe authentication). So i Had to add specific origins. This is my entire setup:
# CORS SETUP
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
'http://localhost:4200',
'http://127.0.0.1:4200'
]
CSRF_COOKIE_HTTPONLY = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_SAMESITE = 'None'
For me it works now with this combination.
I am newbie in Django and try to implement 'autologout' using a tierce app django-session-timeout
It works but I would like to improve behavior
the session expire after time set in settings.py but there is no refresh so that it is disconnect and redirect to login page except if user click elsewhere
in other word, the user is disconnect (as user session expire) but not automatically redirect to login page -> need a user event
is it possible to improve this without writing my own middleware?
settings.py
MIDDLEWARE = [
'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',
'django_session_timeout.middleware.SessionTimeoutMiddleware',
]
LOGIN_URL = 'home'
LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'
SESSION_EXPIRE_SECONDS = 900 # 900 - >15 minutes = 15 * 60
SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_SAVE_EVERY_REQUEST = True
I am trying to implement the single sign-on using Angular, Django, IIS server.
In IIS windows authentication is enabled.
Angular intercepter code :
intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<any>> {
console.log("in intercept")
req = req.clone({
withCredentials: true });
return next.handle(req); }
Django settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.RemoteUserMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',]
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.RemoteUserBackend',)
CORS_ORIGIN_ALLOW_ALL = True
ALLOWED_HOSTS = ["*"]
Getting error:
(IP-address) has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Try this configuration in settings.py
CORS_ORIGIN_ALLOW_ALL = True CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_CREDENTIALS = True # This one is required when you are using withCredentials: true
The problem will lie in the Django setup, please have a look at this link: https://stackoverflow.com/a/38162454/4587598
If at first try won't work, strip all settings.py and setup from scratch, firstly checking if CORS issue does not occur and afterwards add authentication complexity.
try django-cors-headers
pip install django-cors-headers
And set it up
In your settings.py
INSTALLED_APPS = (
...
'corsheaders',
...
)
You will also need to add a middleware class to listen in on responses:
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django's CommonMiddleware
CORS_ORIGIN_ALLOW_ALL = True
I'm having a problem with the csrf token on a Django powered site, which I'm close to reporting as a bug.
Problem is basically, CSRF token fails when DEBUG is False. When DEBUG is False, if I'm using sessions for the csrf token (Django 1.11):
CSRF_USE_SESSIONS = True
CSRF_COOKIE_AGE = None
...all forms/post requests on the frontend fail authentication, but I can login fine to the Django admin panel, e.g., csrf token authentication succeeds.
On the other hand, if I'm using cookies for csrf, authentication on the frontend for forms/post requests go through without any problem, but then it fails for the admin login: CSRF verification failed. Request aborted.
Part of my settings.py file looks like this:
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
DEBUG = 'DEBUG' in os.environ
# CSRF
# These are commented/uncommented depending on what method I'm testing
# CSRF_USE_SESSIONS = True
# CSRF_COOKIE_AGE = None
# I added the cookie domain setting after I started seeing the problem
# and hoped it would have resolved it; it didn't help.
CSRF_COOKIE_DOMAIN = '.{0}'.format(os.getenv('DOMAIN_NAME', 'mysite.com'))
ALLOWED_HOSTS = [
'.mysite.com',
'.mysite.info',
]
if DEBUG:
ALLOWED_HOSTS.extend(['.mysite.dev'])
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'mainsite',
'constance',
'jstemplate',
'compressor',
]
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.middleware.gzip.GZipMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
'mainsite.middleware.Guid',
'mainsite.middleware.SiteLang',
]
If I set DEBUG to True, I have no issues whatsoever with CSRF token authentication, both on the frontend as with logging into the Django admin panel.
I'm also using Redis as a cache. Am I missing something crucial that is causing this CSRF error? I must point out, there was a point in which I was not getting this error, but I cannot for the life of me pinpoint what change would have created this behavior with the CSRF token.
I also have the same issue.
I solve this by
1. pip install django-sslserver.
2. Put sslserver in the INSTALLED_APPS.
3. python manage.py runsslserver
I am using TokenAuthentication in Django REST Framework to have a script remotely access my API. The domain running the API is behind a TLS certificate.
I have scoured through MANY sources, and tried many options before coming here to figure out what my problem is. In short, I continue to get the CSRF verification failed. Request aborted. error when I attempt to post.
Here is my view:
# #csrf_exempt
#api_view(['POST'])
#authentication_classes((TokenAuthentication,))
#permission_classes((permissions.IsAuthenticated,))
def create_object(request):
csrf_exempt decorator has done nothing here. So, I have also tried it on my urls.py:
url(r'^create_object/', csrf_exempt(views.create_object),),
I even tried writing a custom decorator, and using this suggestion. Even when I do this, I cannot even seem to get that decorator to execute before getting the failure. Perhaps there is an issue with the ordering of my middleware?
'sslify.middleware.SSLifyMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsPostCsrfMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
Here are my django cors settings:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = ('example.com',)
CORS_REPLACE_HTTPS_REFERER = True
As promised, here is the solution that I came up with. Admittedly, this is not perfect. I was not able to figure the underlying problem (why on HTTPS the app was not responding to csrf_exempt, or CORS_REPLACE_HTTPS_REFERER), but came up with this limited solution.
STEP 1
First, I subclassed the entire CsrfViewMiddleware class into my own version, and placed it into my middleware (changes from original quertion marked):
'sslify.middleware.SSLifyMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware', ##CHANGE
'myapp.csrf.CsrfViewMiddleware', ##CHANGE
'corsheaders.middleware.CorsPostCsrfMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
At about line 160 of my version of CsrfViewMiddleware, I replaced the existing conditional to this:
acceptable_referers = ['https://%s' % u for u in settings.CORS_ORIGIN_WHITELIST] + ['http://%s' % u for u in settings.CORS_ORIGIN_WHITELIST]
if not same_origin(referer, good_referer) and referer not in acceptable_referers:
This got me past the invalid referer issue, which is fine because I am whitelisting the domains that are okay. It essentially comes to the same result as CORS_REPLACE_HTTPS_REFERER. My version cross-references the referer header with settings.CORS_ORIGIN_WHITELIST, while the CORS_REPLACE_HTTPS_REFERER method temporarily changes the request referer. Neither seems to me a sufficient enough security solution--but that is another conversation.
STEP 2
At this point, I was still getting the csrf cookie not found error. To circumvent this problem, and since csrf_exempt was not respoding (it seemed as if the middleware was executing too early), I added a new piece of middleware:
'sslify.middleware.SSLifyMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'myapp.csrf.CsrfSkipMiddleware' ##ADDED
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware', ##REMOVED
'myapp.csrf.CsrfViewMiddleware', ##ADDED
'corsheaders.middleware.CorsPostCsrfMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
This new piece of middleware essentially sets a flag on the request object (_dont_enforce_csrf_checks) that already exists on the stock version of CsrfViewMiddleware and tells the script to ignore the rest of the csrf check. In order to do that, it checks the page path against a list of paths that I have selected to remove from csrf in settings.CSRF_SKIP_URLS.
class CsrfSkipMiddleware(object):
def process_request(self, request):
CSRF_SKIP_URLS = [re.compile(expr) for expr in settings.CSRF_SKIP_URLS]
path = request.path_info.lstrip('/')
if any(m.match(path) for m in CSRF_SKIP_URLS):
setattr(request, '_dont_enforce_csrf_checks', True)
THOUGHTS
Again, not the best implementation. But, for my purposes it works. Thoughts are still welcome.
I see you're using django cors headers.
I was facing a similar issue and specifying:
CORS_REPLACE_HTTPS_REFERER = True in settings.py resolved the problem.