How to configure CORS in Python Django
Enable Cross-Origin Resource Sharing (CORS) in a Django application using the django-cors-headers package with CORS_ALLOWED_ORIGINS in settings.py.
Configure Cross-Origin Resource Sharing (CORS) in a Python Django application using the
django-cors-headerspackage to allow cross-origin requests from trusted origins.
Prerequisites
- Python 3.10 or later installed.
- A Django 4.2 or later project.
- pip for package management.
Step-by-Step: Enable CORS in Python Django
Install the
django-cors-headerspackage. This package provides Django middleware that adds Cross-Origin Resource Sharing (CORS) response headers:pip install django-cors-headersAdd
corsheadersto theINSTALLED_APPSlist insettings.py:INSTALLED_APPS = [ # ... 'corsheaders', # ... ]Add the CORS middleware to the
MIDDLEWARElist insettings.py. PlaceCorsMiddlewareas high as possible in the list, beforeCommonMiddlewareand any middleware that generates responses:MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... ]Configure the allowed origins in
settings.py. Choose one of the following options depending on the Cross-Origin Resource Sharing (CORS) requirements.Option A: Allow specific origins-- Set
CORS_ALLOWED_ORIGINSto a list of trusted domains:CORS_ALLOWED_ORIGINS = [ 'https://app.example.com', 'https://admin.example.com', ]Option B: Allow all origins-- Set
CORS_ALLOW_ALL_ORIGINStoTruefor public APIs that do not use credentials. Do not use this setting in production for APIs that handle sensitive data:CORS_ALLOW_ALL_ORIGINS = TrueOption C: Allow origins with credentials-- Enable
CORS_ALLOW_CREDENTIALSwhen the front-end sends cookies or authentication headers. This setting requires explicit origins inCORS_ALLOWED_ORIGINS:CORS_ALLOWED_ORIGINS = [ 'https://app.example.com', ] CORS_ALLOW_CREDENTIALS = TrueOption D: Allow specific headers and methods-- Customize the permitted headers and HTTP methods:
CORS_ALLOW_HEADERS = [ 'content-type', 'authorization', 'x-requested-with', ] CORS_ALLOW_METHODS = [ 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', ]Set
CSRF_TRUSTED_ORIGINSif the front-end makes state-changing requests with credentials. Django's Cross-Site Request Forgery (CSRF) protection requires a separate allowlist from CORS:CSRF_TRUSTED_ORIGINS = [ 'https://app.example.com', ]
How to Verify CORS Is Working in Django
Start the Django development server and send a test request with
curl to confirm Cross-Origin Resource Sharing (CORS) headers appear in the response:
curl -I -H "Origin: https://app.example.com" http://localhost:8000/api/data/The response should include:
Access-Control-Allow-Origin: https://app.example.comCommon Issues When Configuring CORS in Django
- Middleware order incorrect.
CorsMiddlewaremust run beforeCommonMiddleware. Django processes middleware top to bottom, and a lower placement may miss theOriginheader. CORS_ALLOW_ALL_ORIGINSwithCORS_ALLOW_CREDENTIALS.The browser rejects responses withAccess-Control-Allow-Origin: *when credentials are included. UseCORS_ALLOWED_ORIGINSwith explicit domains whenCORS_ALLOW_CREDENTIALS = True.- CSRF errors on POST requests.CORS and CSRF are separate mechanisms in Django. Add the front-end origin to both
CORS_ALLOWED_ORIGINSandCSRF_TRUSTED_ORIGINS. - Duplicate headers from reverse proxy.Nginx or Apache adds CORS headers that conflict with Django's headers. Configure CORS in one layer only.
For a detailed explanation of the CORS mechanism, see CORS tutorial: How Cross-Origin Resource Sharing works.