Django, CORS "Access-Control-Allow-Origin" error - django

Can't figure out what's wrong with my Django DRF api endpoint. I'm getting a CORS error
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://127.0.0.1:8000/api/. (Reason: CORS
header ‘Access-Control-Allow-Origin’ missing). Status code: 200.
Problem is, I followed every step online to fix this.
I've installed 'django-cors-headers'
Added corsheaders app to INSTALLED_APPS above rest_framework
and the app that includes api endpoint.
Added cors middleware to the top of the middleware list in
settings.py
Added 'CORS_ALLOWED_ORIGINS = ('http://localhost:3000' # React
app) (Also tried with CORS_ORIGIN_ALLOW = True)
Quadruple-checked that API POST request includes a trailing slash.
Nothing seems to fix it. Am I forgetting something? Thanks for any help.
This is my settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'core.apps.CoreConfig',
]
CORS_ALLOWED_ORIGINS = (
'http://localhost:3000', # for localhost (REACT Default)
)
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'corsheaders.middleware.CorsMiddleware',
'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',
]
Not sure how revelant it is, but If I send POST request from insomnia, it works fine, but from React, it doesn't, this is my react request just in case:
const postSomeData = async () => {
const res = await axios.post(
"http://127.0.0.1:8000/api/",
{ promptQuery: "pls just work already" },
{
headers: {
"Content-Type": "application/json",
},
}
);
};
Thank you!

The code looks fine ,it seems middleware order issue. Would you try putting corsheader middle between sessionmiddleware and commonmiddleware ..
something like this :
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', #here
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
since the order of middleware matters.

Related

Django + Vue 403 Forbidden Error On axios.get

I'm trying to log the user but the Django rest API can't see the current jwt token of the logging user and I'm getting a 403 error. The API is working fine on the Postman with all the Authentication aspects. I have tried some advised solutions but they don't seem to work.
Attempt 1
axios.defaults.headers.common["authorization"] =
"Bearer " + localStorage.getItem("jwt");
await axios.get(api-link)
Attempt 2
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.withCredentials = true;
await axios.get(api-link)
Attempt 3
await axios.get(api-link.{
{
headers:{header stuff}
},
{withCredentials: true}
)
(Basically adding headers and credentials inside the get request.)
Django settings.py
I couldn't find a standard for this, currently I'm using this one for testing:
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',
'corsheaders',
'users',
]
MIDDLEWARE = [
'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.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = ['http://127.0.0.1:8000', 'http://localhost:8000']
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
]
}
CSRF_COOKIE_NAME = "XSRF-TOKEN"

Some static files can't be loaded because it is blocked by CORS policy (Django) even it is configured based on Django documentation

I faced an issue with a CORS policy and cannot see what is wrong.
I use Django framework and my static files are hosted in Azure Blob
So I am getting errors for these files and it says tuat Access-Control-Allow-Origin is not present:
What is strange that other files from the same host are loaded..
CORS settings looks like this:
ALLOWED_HOSTS = ['https://support.mdesk.lt', 'https://suppaccountstorage.blob.core.windows.net']
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
'https://support.mdesk.lt',
'https://suppaccountstorage.blob.core.windows.net',
)
CSRF_TRUSTED_ORIGINS = ['https://support.mdesk.lt']
INSTALLED_APPS = [
'corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django.contrib.humanize',
'bootstrap4form',
'supportSystem',
'storages'
]
SITE_ID = 1
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',
]
Wham am I doing wrong?
Loading fonts from a different origin is affected by the CORS settings (your CSS files seem to be fine). Since your assets are not served by the Django application but by the Azure storage you need to adjust the CORS settings there (they will not be processed by the Django middleware you are using). You can change the settings in the Azure Portal.

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 = ["*"]

Django RestFrameWork Post Request with csrf

I am a newbie to django/django-rest-framework. I am experimenting with React for the frontend and Django-rest-framework for the backend. The client and server are on different domains. I was able to make a GET request, for POST request I also manage to do it but only with the csrf_exempt decorator, which is not ideally. The django documentation recommended me to use CSRF_TRUSTED_ORIGINS to avoid csrf verification but that also doesn't work for me. Here's my settings.py
INSTALLED_APPS = [
'api.apps.ApiConfig',
'rest_framework',
'corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'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.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_WHITELIST = (
'localhost:3000',
)
CSRF_TRUSTED_ORIGINS = [
'localhost:3000'
]
Should I start implementing jwt-authentication to avoid this situation ? What is the best approach to this problem?

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.