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