How can I enable CORS on Django REST Framework
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Cross-Origin Resource Sharing (CORS) controls whether a browser allows JavaScript on one domain to make requests to a different domain. When your Django REST Framework API runs on api.example.com and your frontend runs on app.example.com, the browser blocks requests unless the API sends the correct CORS headers. The django-cors-headers package is the standard solution.
Install and Configure django-cors-headers
Install the package and add it to your Django settings.
The CorsMiddleware must appear before any middleware that generates responses (especially CommonMiddleware) so it can add headers to all responses including error pages.
Allow Specific Origins (Recommended)
Whitelist the exact origins that should access your API.
This is the safest configuration for production. Only listed origins receive Access-Control-Allow-Origin headers.
Allow All Origins (Development Only)
For local development where frontend and API run on different ports:
This sends Access-Control-Allow-Origin: * for every request. Never deploy this to production — it allows any website to make requests to your API.
Allow Origins by Regex Pattern
When you need to support multiple subdomains or dynamic environments:
Regex patterns are checked when the origin does not match CORS_ALLOWED_ORIGINS exactly.
Configure Allowed Methods and Headers
By default, django-cors-headers allows standard methods and headers. Customize when your API uses non-standard headers:
Enable Credentials (Cookies and Auth Headers)
If your API uses session cookies or HTTP authentication:
The browser refuses to send credentials to a * origin. You must list specific allowed origins when credentials are enabled.
Expose Custom Response Headers
If your API returns custom headers that the frontend needs to read:
Without this, the browser hides non-standard response headers from JavaScript.
Complete Production Example
Common Pitfalls
- Placing
CorsMiddlewareafterCommonMiddleware— the CORS headers never get added because responses are already generated. - Using
CORS_ALLOW_ALL_ORIGINS = TruewithCORS_ALLOW_CREDENTIALS = True— browsers reject this combination. Use explicit origin lists with credentials. - Forgetting to add
corsheaderstoINSTALLED_APPS— the middleware loads but configuration settings are ignored. - Confusing
CORS_ALLOWED_ORIGINS(list of strings) withCORS_ALLOWED_ORIGIN_REGEXES(list of regex patterns) and mixing the formats. - Not handling preflight
OPTIONSrequests —django-cors-headershandles these automatically, but custom middleware that short-circuits responses can block them.
Summary
- Install
django-cors-headersand addCorsMiddlewarebeforeCommonMiddleware. - Use
CORS_ALLOWED_ORIGINSwith explicit origin URLs for production. - Use
CORS_ALLOW_ALL_ORIGINS = Trueonly during local development. - Set
CORS_ALLOW_CREDENTIALS = Truewith specific origins when using cookies or auth headers. - Add custom headers to
CORS_ALLOW_HEADERSandCORS_EXPOSE_HEADERSas needed.

