Django CORS Headers
django-cors-headers is a Django application that simplifies the handling of server headers required for Cross-Origin Resource Sharing (CORS). It provides a robust and flexible solution to manage cross-origin requests, allowing Django applications to securely interact with frontend applications hosted on different domains. The current version is 4.9.0, and it maintains an active release cadence with regular updates and community support.
Warnings
- gotcha Middleware order is critical. `CorsMiddleware` must be placed at the very top of your `MIDDLEWARE` list, before any other middleware (like `SecurityMiddleware` or `CsrfViewMiddleware`) that might block preflight `OPTIONS` requests or prevent CORS headers from being added correctly.
- breaking Since version 3.0.0, `CORS_ORIGIN_WHITELIST` was renamed to `CORS_ALLOWED_ORIGINS`. Additionally, allowed origins now *require* URI schemes (e.g., 'https://example.com' instead of 'example.com') and optionally ports, fixing a security issue with scheme-mixing.
- gotcha Avoid using `CORS_ALLOW_ALL_ORIGINS = True` in production environments as it poses a significant security risk by allowing any domain to access your resources. Be specific with `CORS_ALLOWED_ORIGINS`.
- gotcha If you are sending credentials (like cookies or authorization headers) from your frontend, you must set `CORS_ALLOW_CREDENTIALS = True` in your Django settings and also configure your frontend client (e.g., `withCredentials: true` for Axios or `credentials: 'include'` for Fetch API). Additionally, be aware of Django's `SESSION_COOKIE_SAMESITE` setting (default 'Lax' in Django 2.1+) which might prevent session cookies from being sent cross-domain; change to 'None' if needed.
- gotcha If you are serving static files or other assets from a different domain (e.g., a CDN or cloud storage like GCP), CORS headers must be configured on the *server hosting those assets*, not just in your Django application. `django-cors-headers` only handles headers for requests served by Django itself.
- deprecated The `CORS_REPLACE_HTTPS_REFERER` setting and `CorsPostCsrfMiddleware` were removed. For making CSRF checks pass for CORS requests, Django's `CSRF_TRUSTED_ORIGINS` setting is the preferred and modern solution.
Install
-
pip install django-cors-headers
Imports
- CorsMiddleware
from corsheaders.middleware import CorsMiddleware
Quickstart
# settings.py
INSTALLED_APPS = [
# ... other apps
'corsheaders',
# ...
]
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',
# ... other middleware
]
# Whitelist specific origins. In production, avoid CORS_ALLOW_ALL_ORIGINS = True.
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"http://127.0.0.1:3000",
# Add your frontend domains here, e.g., "https://yourfrontend.com"
]
# Optional: Allow credentials (cookies, auth headers) to be sent cross-origin
# CORS_ALLOW_CREDENTIALS = True
# Optional: If you need to allow all origins for development (use with caution in production!)
# CORS_ALLOW_ALL_ORIGINS = False # Set to True for development, but remove for production
# Example for allowing specific HTTP methods if you deviate from default allowed methods
# CORS_ALLOW_METHODS = [
# 'DELETE',
# 'GET',
# 'OPTIONS',
# 'PATCH',
# 'POST',
# 'PUT',
# ]