CORS in Django — Configuring Cross-Origin Requests with django-cors-headers
In this tutorial, you will learn about CORS in Django. We cover key concepts, practical examples, and best practices to help you master this topic.
Django provides CORS support through the django-cors-headers package, which adds middleware for handling CORS headers, preflight requests, and configurable origin, method, and header whitelists.
What You'll Learn
- Installing and configuring django-cors-headers
- Setting up CORS middleware in settings.py
- Configuring allowed origins, methods, and headers
Why It Matters
Django powers many content-heavy and enterprise APIs. Proper CORS configuration enables secure cross-origin access for React, Vue, and Angular frontends. DodaTech's content management API uses Django with django-cors-headers.
flowchart LR
A["Django Settings"] --> B["INSTALLED_APPS"]
A --> C["MIDDLEWARE"]
A --> D["CORS_ALLOWED_ORIGINS"]
B --> E["corsheaders"]
C --> F["CorsMiddleware"]
D --> G["Origin whitelist"]
Code Examples
# Django settings.py CORS configuration
INSTALLED_APPS = [
# ...
'corsheaders',
# ...
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
# ...
]
# Configure allowed origins
CORS_ALLOWED_ORIGINS = [
"https://app.example.com",
"https://admin.example.com",
"https://dashboard.example.com",
]
# Or allow all origins (development only)
CORS_ALLOW_ALL_ORIGINS = False # Never True in production
# Allow credentials
CORS_ALLOW_CREDENTIALS = True
# Configure allowed methods and headers
CORS_ALLOW_METHODS = [
'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'
]
CORS_ALLOW_HEADERS = [
'accept', 'authorization', 'content-type',
'origin', 'x-csrftoken', 'x-requested-with',
]
# Expose custom headers to JavaScript
CORS_EXPOSE_HEADERS = [
'x-ratelimit-remaining', 'x-request-id'
]
# Preflight cache duration
CORS_PREFLIGHT_MAX_AGE = 86400 # 24 hours
# Per-view CORS configuration
from corsheaders.decorators import cors_allow_all
from django.http import JsonResponse
@cors_allow_all()
def public_view(request):
return JsonResponse({"data": "public"})
# Or with specific origins
from corsheaders.decorators import cors_allow_origin
@cors_allow_origin("https://admin.example.com")
def admin_view(request):
return JsonResponse({"data": "admin"})
# Regex-based origin matching
CORS_ALLOWED_ORIGIN_REGEXES = [
r"^https://[\w-]+\.example\.com$",
r"^https://(www\.)?app\.example\.com$",
]
# Test Django CORS configuration
curl -I -H "Origin: https://app.example.com" \
http://localhost:8000/api/data | grep -i "access-control"
curl -I -H "Origin: https://evil.com" \
http://localhost:8000/api/data | grep -i "access-control"
Common Mistakes
1. Not Placing CorsMiddleware Before CommonMiddleware
CorsMiddleware must be placed before CommonMiddleware in the MIDDLEWARE list.
2. Using CORS_ALLOW_ALL_ORIGINS in Production
This allows any website to read API responses. Always use CORS_ALLOWED_ORIGINS.
3. Forgetting CSRF Token Exemption for OPTIONS
Django CSRF middleware blocks OPTIONS requests. Add corsheaders to CSRF_TRUSTED_ORIGINS.
4. Not Setting CSRF_COOKIE_SAMESITE for Cross-Origin
Cross-origin requests with credentials need CSRF_COOKIE_SAMESITE = 'None' and CSRF_COOKIE_SECURE = True.
5. Using Origin Without Trailing Slashes
CORS_ALLOWED_ORIGINS entries should not have trailing slashes.
Practice Questions
- What package provides CORS support in Django?
- Where should CorsMiddleware be placed in the MIDDLEWARE list?
- How do you allow credentials in Django CORS?
- What setting allows all origins (development only)?
- How do you configure regex-based origin matching?
Answers:
- django-cors-headers.
- Before CommonMiddleware, typically at the top of the MIDDLEWARE list.
- Set CORS_ALLOW_CREDENTIALS = True.
- CORS_ALLOW_ALL_ORIGINS = True.
- Use CORS_ALLOWED_ORIGIN_REGEXES with a list of regex patterns.
Challenge: Build a Django REST Framework API with tiered CORS configuration: public endpoints with open CORS, authenticated endpoints with restricted origins, and admin endpoints with strict origin and credential requirements.
FAQ
Mini Project
Build a Django REST API with three tiers of CORS configuration. Implement django-cors-headers for public, partner, and admin endpoints. Add Django REST Framework authentication, CSRF protection with cross-origin cookies, and automated tests using pytest that validate CORS behavior for each endpoint tier.
What's Next
Now explore framework-specific CORS for Express, FastAPI, and other platforms.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro