How can I enable CORS on my Django REST Framework? the reference doesn't help much, it says that I can do by a middleware, but how can I do that?
-
Django REST has package django-cors-headers, `settings..py` can have CORS_ORIGIN_WHITELIST to set Access-Control-Allow-Origin. See: https://stackoverflow.com/a/49520118/1548275 – Jari Turkia Feb 21 '22 at 19:22
12 Answers
The link you referenced in your question recommends using django-cors-headers
, whose documentation says to install the library
python -m pip install django-cors-headers
and then add it to your installed apps:
INSTALLED_APPS = (
...
'corsheaders',
...
)
You will also need to add a middleware class to listen in on responses:
MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...,
]
and specify domains for CORS, e.g.:
CORS_ALLOWED_ORIGINS = [
'http://localhost:3030',
]
Please browse the configuration section of its documentation, paying particular attention to the various CORS_ORIGIN_
settings. You'll need to set some of those based on your needs.

- 127,765
- 105
- 273
- 257
-
2do you know any other way to do that, without the need to install a new dependency? I am trying to create a middleware class now – Julio Marins Mar 03 '16 at 00:50
-
15@JulioMarins, why would you write your own version when this is readily available and easily installable, with 12 releases, 21 contributors, over 800 stars and over 100 forks? – ChrisGPT was on strike Mar 03 '16 at 00:52
-
3You have a point indeed, but since the only need for a simple CORS is a header `Access-Control-Allow-Origin: *` I don't see why load a whole thing, I will put another way to do this in your answer so both methods can be available. reference: [link(]http://enable-cors.org/server.html) – Julio Marins Mar 03 '16 at 01:17
-
2@JulioMarins, that would be the sledgehammer approach. If you look at the configuration link I provided you'll see that `django-cors-headers` is much more flexible than that. If you would prefer to create your own class, be my guest. But I'd be using that library. – ChrisGPT was on strike Mar 03 '16 at 01:20
-
5@Chris I think you should add [CORS_ORIGIN_WHITELIST](https://github.com/ottoyiu/django-cors-headers/#cors_origin_whitelist) so that you whitelist the calling host. – Hakim Sep 24 '17 at 21:32
-
This article gives example to allow CORS without extra package: https://www.techiediaries.com/django-cors/ – nos Jul 08 '18 at 20:00
-
@nos, that blog post doesn't improve much on [Julio's existing answer](https://stackoverflow.com/a/35761458/354577), which has the benefit of being fully contained on Stack Overflow and therefore not subject to link rot. – ChrisGPT was on strike Jul 08 '18 at 22:29
-
-
@Viraj, even _Django_ doesn't support Django version < 1.11 anymore. Version 1.10 stopped receiving extended support on December 2, 2017. If you're still using 1.10 or earlier I urge you to upgrade. See https://www.djangoproject.com/download/#supported-versions – ChrisGPT was on strike May 09 '19 at 13:32
-
@Viraj, but note that support for earlier versions of Django [was](https://github.com/ottoyiu/django-cors-headers/blob/master/HISTORY.rst#250-2019-03-05) recently [removed](https://github.com/ottoyiu/django-cors-headers/commit/6a28e29774d2a25ed736163cc239449ff9448a53) from `django-cors-headers`. Again, a _much better_ solution is to upgrade Django, but if you're stuck on 1.8, 1.9, or 1.10 and upgrading is impossible you could use [`django-cors-headers` version 2.4.1](https://github.com/ottoyiu/django-cors-headers/releases/tag/2.4.1). – ChrisGPT was on strike May 09 '19 at 13:35
-
Do I need to add `CSRF_TRUSTED_ORIGINS` as well (https://github.com/adamchainz/django-cors-headers#csrf-integration) – Robert Johnstone Jun 24 '20 at 10:00
-
If the above steps didn't help - Make sure you added the trailing comma. – Ido Savion Jun 26 '21 at 15:23
-
I need some clarification: I am having a Django web app in which I set my react app in a folder inside the Django project folder. when I make a request to get data from Django server (127.0.0.1:8000/api/resource) Postgres database, from React app localhost:3000, even after setting all the required parameters in my settings.py, I still get the following error: ....has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. I have even tried all the settings given on this stack page...still not getting data... – vially Nov 21 '21 at 09:31
-
This worked for us. Just that we were running the application on a docker container, instead of installing `django-cors-headers` via the above command, we had to have `django-cors-headers==3.13.0` in requirements.txt which is installed when building the container. – Tashi Feb 14 '23 at 10:52
python -m pip install django-cors-headers
and then add it to your installed apps:
INSTALLED_APPS = [
...
'corsheaders',
...
]
You will also need to add a middleware class to listen in on responses:
MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...,
]
CORS_ALLOW_ALL_ORIGINS = True # If this is used then `CORS_ALLOWED_ORIGINS` will not have any effect
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
'http://localhost:3030',
] # If this is used, then not need to use `CORS_ALLOW_ALL_ORIGINS = True`
CORS_ALLOWED_ORIGIN_REGEXES = [
'http://localhost:3030',
]
more details: https://github.com/ottoyiu/django-cors-headers/#configuration
read the official documentation can resolve almost all problem

- 13,359
- 7
- 71
- 99

- 2,138
- 1
- 15
- 9
-
4Adding the four lines you added to @Chris's answer was necessary for this to work for me. – Matt Jun 08 '18 at 05:13
-
10Why is `CORS_ORIGIN_ALLOW_ALL = True`, but `CORS_ORIGIN_WHITELIST` is still set? [The docs](https://github.com/ottoyiu/django-cors-headers/#cors_origin_allow_all) seem to make it seems like this is not required and seems to be confusing for the answer here. – phoenix Jan 12 '19 at 19:22
-
CORS_ORIGIN_ALLOW_ALL If True, the whitelist will not be used and all origins will be accepted. – BjornW Mar 27 '19 at 20:42
-
9Also keep in mind `'corsheaders.middleware.CorsMiddleware',` needs to be rather at the top of the list, otherwise the connection may be rejected prior to getting to it. – Sebastián Vansteenkiste Aug 22 '19 at 14:34
-
-
You can do by using a custom middleware, even though knowing that the best option is using the tested approach of the package django-cors-headers
. With that said, here is the solution:
create the following structure and files:
-- myapp/middleware/__init__.py
from corsMiddleware import corsMiddleware
-- myapp/middleware/corsMiddleware.py
class corsMiddleware(object):
def process_response(self, req, resp):
resp["Access-Control-Allow-Origin"] = "*"
return resp
add to settings.py
the marked line:
MIDDLEWARE_CLASSES = (
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
# Now we add here our custom middleware
'app_name.middleware.corsMiddleware' <---- this line
)

- 10,039
- 8
- 48
- 54
-
1Thanks Julio! Your middleware code should be updated with @masnun code sample. Also, the import doesn't work for me, importing from . fixes the issue: `from . import corsMiddleware` – Pavel Daynyak May 10 '20 at 15:58
-
What about this? 'corsheaders.middleware.CorsMiddleware', No need to add? – reza_khalafi Jan 28 '23 at 16:45
In case anyone is getting back to this question and deciding to write their own middleware, this is a code sample for Django's new style middleware -
class CORSMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
response["Access-Control-Allow-Origin"] = "*"
return response

- 11,635
- 4
- 39
- 50
For Django versions > 1.10, according to the documentation, a custom MIDDLEWARE can be written as a function, let's say in the file: yourproject/middleware.py
(as a sibling of settings.py
):
def open_access_middleware(get_response):
def middleware(request):
response = get_response(request)
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Headers"] = "*"
return response
return middleware
and finally, add the python path of this function (w.r.t. the root of your project) to the MIDDLEWARE list in your project's settings.py
:
MIDDLEWARE = [
.
.
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'yourproject.middleware.open_access_middleware'
]
Easy peasy!

- 2,140
- 1
- 18
- 16
-
The approach posted before uses MIDDLEWARE_CLASSES and not MIDDLEWARE. This technique works so the downvote was uncalled for :) @JulioMarins – Dhruv Batheja Dec 03 '18 at 14:15
-
1dude, the solution is the same. You're arguing about implementation on the Django version. Your code is also with wrong indentation on `open_access_middleware`. – Julio Marins Dec 03 '18 at 18:12
Updated 2022 and adding a new use case
When your using Axios POST with the option withCredentials: true
, there are a few additional options to consider.
I used this specific case for authentification over Basic or/and Session login.
To Avoid error messages as:
Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
And the above mentioned by others. I solved the issue in this way.
[IP addresses are from my local example, have in mind to change it]
setting.py
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
'rest_framework.authtoken',
...
]
ALLOWED_HOSTS = ["localhost","192.168.0.50"]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000', # for localhost (REACT Default)
'http://192.168.0.50:3000', # for network
'http://localhost:8080', # for localhost (Developlemt)
'http://192.168.0.50:8080', # for network (Development)
)
CSRF_TRUSTED_ORIGINS = [
'http://localhost:3000', # for localhost (REACT Default)
'http://192.168.0.50:3000', # for network
'http://localhost:8080', # for localhost (Developlemt)
'http://192.168.0.50:8080', # for network (Development)
]
MIDDLEWARE = [
...
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsMiddleware',
...
]
On the browser, the Axios request headers must be send and on the server site the headers must be permitted. If not, the error message will be.
Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
Up to this moment play with the headers. You can add more headers if you need them, like:
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
Cheers :)

- 166
- 1
- 4
Below are the working steps without the need for any external modules:
Step 1: Create a module in your app.
E.g, lets assume we have an app called user_registration_app. Explore user_registration_app and create a new file.
Lets call this as custom_cors_middleware.py
Paste the below Class definition:
class CustomCorsMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = self.get_response(request)
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Headers"] = "*"
# Code to be executed for each request/response after
# the view is called.
return response
Step 2: Register a middleware
In your projects settings.py file, add this line
'user_registration_app.custom_cors_middleware.CustomCorsMiddleware'
E.g:
MIDDLEWARE = [
'user_registration_app.custom_cors_middleware.CustomCorsMiddleware', # ADD THIS LINE BEFORE CommonMiddleware
...
'django.middleware.common.CommonMiddleware',
]
Remember to replace user_registration_app with the name of your app where you have created your custom_cors_middleware.py module.
You can now verify it will add the required response headers to all the views in the project!

- 2,578
- 26
- 18
Updated 2021 for all those who have the latest version of Django v3.x.x, The steps to allow CORS from any origin are given below.
Step 1: Install required library
pip install django-cors-headers
Step 2: Then add in proper place in your INSTALLED_APPS in settings.py
- after the rest_framework
and before your application myapp
'rest_framework',
'corsheaders',
'myapp.apps.MyAppConfig',
Step 3: Allow the origins for your api (inside settings.py
)
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000', # for localhost (REACT Default)
'http://192.168.10.45:3000', # for network
)

- 2,521
- 1
- 28
- 38

- 464
- 5
- 13
Well, I don't know guys but:
using here python 3.6 and django 2.2
Renaming MIDDLEWARE_CLASSES to MIDDLEWARE in settings.py worked.

- 641
- 1
- 6
- 13
first install django package
pip install django-cors-headers
and add to apps in settings file
INSTALLED_APPS = (
...
'corsheaders',
...
)
and then add cors middle ware to setting file
MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...,
]
and finally add cross orgin whitelist
#CORS_ORIGIN_ALLOW_ALL = True
#CORS_ALLOW_CREDENTIALS = True
#CORS_ALLOW_HEADERS = ['*']
CORS_ORIGIN_WHITELIST = ('http://localhost:5000',)
that will solve cors error easily. happy coding

- 695
- 11
- 22
Django=2.2.12 django-cors-headers=3.2.1 djangorestframework=3.11.0
Follow the official instruction doesn't work
Finally use the old way to figure it out.
ADD:
# proj/middlewares.py
from rest_framework.authentication import SessionAuthentication
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
return # To not perform the csrf check previously happening
#proj/settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'proj.middlewares.CsrfExemptSessionAuthentication',
),
}

- 4,348
- 29
- 43
After trying every suggested solution and nothing seemed to work. I finally fixed the issue after much frustration by clearing my browser cache...
Then the accepted answer works by using django-cors-headers
.
Hope this helps someone else!

- 742
- 1
- 6
- 15