CORS issue with react and django-rest-framework - django

I'm using react on the frontend side and Django on the backend. I using django-cors-headers
for managing CORS in my Django app.
I have added the package in INSTALLED_APPS like this:-
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework.authtoken',
'rest_framework',
'corsheaders',
'services',
'feeds',
'knox',
'users',
]
then I have also added same in MIDDLEWARE
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',
'django.middleware.common.CommonMiddleware',
]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
ALLOWED_HOSTS = ['*']
and I'm passing CORS headers from my client-side React app like:-
const Axios = axios.create({
baseURL: `${BASE_URL}/api`,
timeout: 1000,
headers: {
'X-Custom-Header': 'foobar',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
}
})
Error on frontend:-
Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/register' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.

Access-Control-Allow-Origin header is sent by server, not by frontend. Server also does not send this header always. Whenever client sends origin header, only then server sends Access-Control-Allow-Origin and when origin is not matched, CORS error in thrown. If you used create-react-app to bootstrap your react project, they have really nice documentation how to configure proxy, that way you dont have to configure CORS on backend. In django configuration try to remove ALLOWED_HOSTS = ['*'] line, CORS_ORIGIN_ALLOW_ALL = True should work for all.

there was a bug in my client-side headers'X-Custom-Header': 'foobar', after removing it started working fine

Related

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8000/api/task-list/

I'm working on a vuejs and django rest single page application.
the problem is so clear, that I'm getting the Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource error.
My vuex code be like:
mutations:{
addTask: function(){
axios({
url: 'http://127.0.0.1:8000/api/task-list/',
method: 'POST',
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
}).then(response => {
console.log(response.data);
}).catch(err => {
console.log(err.response);
})
}
},
and my django rest urls.py, in my django application urls:
urlpatterns = [
path('task-list/', TaskList.as_view()),
path('task-create/', TaskCreate.as_view())
]
and my main app urls:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('task.urls')),
path('api/', include('authentication.urls')),
path('home/', returnHome)
]
my views.py code:
class TaskList(APIView):
def get(self, request):
tasks = Task.objects.all()
serialized = TaskSerializer(tasks, many=True)
return Response(serialized.data, status=200)
my vue app is running on http://localhost:8080, so I installed django cors headers, configured it like the below code:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# rest api
'rest_framework',
'rest_framework.authtoken',
'corsheaders',
# my apps
'authentication',
'task'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ALLOWED_ORIGINS = [
'http://localhost:8080',
'https://localhost:8080'
]
Although, I'm still getting the Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8000/api/task-list/. (Reason: CORS request did not succeed) Error!
I even tried CORS_ALLOW_ALL_ORIGINS = True , but there are still no changes...
Is there something I'm doing wrong here? I searched a lot about this, but everywhere the solution was about to write the correct configuration for corsheaders.
You problem is the placement of the Django middleware, especially relatively to CommonMiddleware. It should be listed higher than it.
From django-cors-headers README:
CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django's CommonMiddleware or Whitenoise's WhiteNoiseMiddleware. If it is not before, it will not be able to add the CORS headers to these responses.
Also if you are using CORS_REPLACE_HTTPS_REFERER it should be placed before Django's CsrfViewMiddleware (see more below).

django-cors-header not working as expected when using Postman

I'm trying to use my DRF API in my React Web App with Axios but I'm getting CORS policy blocked.
I've checked the headers using POSTMAN and seems like django-cors-header is not actually embedding the Access-Control-Allow-Origin: *
This is my settings.py from Django:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'trvl',
'rest_framework',
'coreapi',
'django_filters',
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = False
And this is what I get from POSTMAN
How can I fix this so every response has the Access-Control-Allow-Origin : *
I had the exact same scenario as you. Same frontend and backend.
I was able to resolve my issue by adding this to my settings.py in addition to everything you listed.
CORS_REPLACE_HTTPS_REFERER = True
In settings.py
set ALLOWED_HOSTS = [] to ALLOWED_HOSTS = ["*"]

No 'Access-Control-Allow-Origin' header is present on the requested resource Django and ReactJS

Currently I have Django 1.98 as Backend and React as Front End.
I'm getting this error:
Access to XMLHttpRequest at
'https://mywebsite:8000/uploads/vtt/' from origin
'http://localhost:3000' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I installed django-cors-headers==2.4.0 on my virtualenviroment
This is my settings.py file:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'uploads.core',
'corsheaders',
]
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True
CSRF_TRUSTED_ORIGINS = ['http://127.0.0.1:3000','http://localhost:3000','http://localhost:8000','https://mywebsite:8000','https://myapp.firebaseapp.com','https://mywebsite:8088']
CSRF_COOKIE_NAME = "csrftoken"
CSRF_HEADER_NAME = [
'HTTP_X_CSRFTOKEN'
]
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CORS_ORIGIN_WHITELIST = ['http://localhost:3000','https://mywebsite:8088']
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
Any idea how to solve it?
Thanks.
django-cors-headers is reasonably fool-proof and your configuration seems correct to me.
There is however a gotcha I've had issues with too:
Your uploads directory is likely not served through Django, but by the server directly as a static file (best practice and nearly default behaviour in Django). Even the built-in development server will serve static files without invoking your Django app.
Since your app is not invoked, django-cors-headers cannot apply a CORS header to those responses.
Make sure https://mywebsite:8000/uploads/vtt/ is the correct URL.
In my case, I used the wrong port because my API used a different port.
I replaced 8000 with 52130.
Try adding:
CORS_ORIGIN_WHITELIST = (
'example.com',
'localhost:3000',
'127.0.0.1:3000',
'more.domain.or.subdomains'
)
Don't forget add the middleware too
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
I had the same issue, and I think is a problem with:
SECURE_SSL_REDIRECT = True
I don't know the impacts over disabling it, but setting it to:
SECURE_SSL_REDIRECT = False
This make the cors problem gone.

Django-rest cross origin request fails

I have installed django-cors-headers and my seetings.py has following:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'rest_framework_docs',
'tasks'
]
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',
]
CORS_ORIGIN_ALLOW_ALL = True
However, I still get Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response error when I hit the url from my Angular frontend.
Am I missing any configuration?
You need to add:
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = False
To your settings.py too and it will work ;)
The problem wasn't on backend side, I had a function in my angular service as following:
getTasks(): Observable<Task[]> {
let headers = new Headers({ 'Access-Control-Allow-Origin': '*' });
let options = new RequestOptions({ headers: headers });
return this.http.get(this.taskUrl, options)
.map(this.extractData)
.catch(this.handleError);
}
Which had to be:
getTasks(): Observable<Task[]> {
return this.http.get(this.taskUrl)
.map(this.extractData)
.catch(this.handleError);
}
In my case it worked when backend(django) and frontend(angular) worked on the same hosts. Like django server on localhost:8000 and angular server on localhost:4200.

Django Angular cors error: access-control-allow-origin not allowed

I have implemented auth in my django app using django-rest-auth. My settings in settings.py:
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'django.contrib.sites',
'allauth',
'allauth.account',
'rest_auth.registration',
'corsheaders',
'rest_framework_docs',
'tasks'
]
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',
]
ROOT_URLCONF = 'urls'
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
ALLOWED_HOSTS = ['*']
SITE_ID = 1
I am logged in from my frontend- I receieved a token with I have stored in my local storage. Now I making a simple GET request like following:
getTasks(): Observable<Task[]> {
let headers = new Headers({ 'Access-Control-Allow-Origin': '*' });
let options = new RequestOptions({ headers: headers, withCredentials: true });
return this.http.get(this.taskUrl, options)
.map(this.extractData)
.catch(this.handleError);
}
But it gives me : Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response. although I am including withCredentials.
What am I doing wrong?
P.S: If I remove options from POST then there is no error but I get incorrect data because my backend returns data for a specific user.
Remove this line,
let headers = new Headers({ 'Access-Control-Allow-Origin': '*' });
from your getTasks() function. You don't need to specify those options to the server. django-cors-headers takes care of that.