Django CORS headers whitelist doesn't work - python

I'm working on an existing code base which consists of a Django backend and a ReactJS frontend.
Everything is dockerized so I'm running the backend on localhost:8001 and the frontend on localhost:3000.
Because I got CORS errors in the browser, I added django-cors-headers to Django. When I add CORS_ORIGIN_ALLOW_ALL = True however, I get an error saying
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ‘http://127.0.0.1:8001/devices/’. (Reason: Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’).
So then I added the following settings:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
'http//:127.0.0.1:3000',
'http//:127.0.0.1:8001',
)
But than I get an error saying
CORS header ‘Access-Control-Allow-Origin’ missing
Why is the whitelist not working? Am I doing something wrong here?

Install any cross origin browser extension in Your browser when you run front end code locally,it will helpful.
and change the whitelist url as below (//: should be ://):
CORS_ORIGIN_WHITELIST = (
'http://127.0.0.1:3000',
'http://127.0.0.1:8001',
)

When you have CORS_ORIGIN_ALLOW_ALL = True, this will set the Access-Control-Allow-Origin: * and as the error suggests while allowing all the domains for cross-origin requests, you can't pass credentials flag with the request. So if you want to keep the header as Access-Control-Allow-Origin: *, the easiest fix would be to not use the credentials flag while sending the CORS request from the frontend.
If you want to allow only a certain domains (which is preferable), you need to find the valid domains first. Remember these domains are the originating domains from where requests are coming to Django. You can find them by looking at request.META.REMOTE_HOST. request.META is the environment seen and passed on by WSGI, and if you have some proxies in between that will give you the last host in the proxy chain.
If you have a web server that talks WSGI e.g. nginx, it will pass on the REMOTE_HOST to your Django application or to any intermediate WSGI server you have (e.g. uWSGI/gunicorn) and they will in turn pass that to your app.
Also, in your settings, the URLs in CORS_ORIGIN_WHITELIST are in wrong format; the separator between scheme and netloc is ://, not //: e.g.:
http://127.0.0.1:3000

Related

REACT + DJANGO - CORS Errors After Login - CORS header ‘Access-Control-Allow-Origin’ missing

We have a React + Django application on GCP App Engine instances and we are facing a CORS error when fetching data through our REST API.
We have already installed and configured the CORS package for the Django Rest Framework in our django application:
`
ALLOWED_HOSTS = [
'xxxxxxxxxxxx.appspot.com',
'yyyyyyyyyyyy.appspot.com',
]
CORS_ALLOWED_ORIGINS=[
'http://localhost:3000',
'https://xxxxxxxxxxxx.appspot.com',
'https://yyyyyyyyyyyy.appspot.com',
]
CORS_ALLOW_CREDENTIALS=True
`
The preflight request is successful as well as the application login, which performs an async request to our backend:
access-control-allow-origin: https://xxxxxxxxxxxxxxxxxxxxx.appspot.com
access-control-allow-headers: accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with
access-control-allow-methods: DELETE, GET, OPTIONS, PATCH, POST, PUT
access-control-max-age: 86400
The correct URL is passed through the allow-origins header. The actual GET request is then blocked with a 400 response code from the browser and the following error message:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xxxxxx.appspot.com/api/entities?page_size=10. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 400.
The strangest thing is that we are able to login into the application and that uses an async request to the same domain, only after we login does this error appear.
We have gone through several stackoverflow pages and different configurations (Eg. Using Regex in he allow ORIGINS configuration) but nothing seems to work, the application always returns the CORS error.
Does anyone have any idea of what might be going on here?
After some debugging, we realized that the CORS error was actually masking another issue, related with the size of the cookies, that exceeded the allowed limit of the server.
The only way to view this error was to go to the network tab and preview the response data in Firefox, in Edge the response was empty, and we were not able to understand the real problem.

Get the URL of a server

I am using flask and flask email for sending an email. When I work on I used the localhost as a base url. I deployed it on the server and email sent is still showing with localhost address.
For example
base_url = "http://localhost:0.0.0.6465"
url=base_url+'/login'
I sent an email(i am using flask-mail) with the url and I can login with the url.
With the same script when I deployed on the server I am getting with same localhost address.I need the server URL should be the base url.
To debug this I tried
url=request.base_url+'/login'
I am getting 404 error in the browser if I use this. I dont want to change the initializtion of base_url because I have to use both in the local as well as in the server.
How can I do that?
You can get the URL to the currently running app through request.host_url. But what you really want to to do to get an external URL to a specific part of your application, is to use url_for as you'd do when referencing your regular endpoints, but with the parameter _external=True:
Given that you have:
#app.route('/login')
def login():
....
You can generate an external URL by using:
from flask import (
url_for,
)
...
url = url_for('login', _external=True)
This will also take into account any proxies in front of your application if you need that, as long as you've used the ProxyFix middleware when setting up your app object.
Since this uses the same mechanism as Flask uses when generating URLs between different pages, it should behave just as you want - i.e. it'll work both on localhost and on the remote host.

Permanently Redirect http to https on Google App Engine Flexible with Django

I'm working on a project that uses Google Cloud Platform's App Engine in the Python 3 Flexible Environment using Django, and I'm trying to permanently redirect all requests over http to https for all routes, but so far have not been successful. I can access the site over https, but only if explicitly written in the address bar.
I've looked at this post: How to permanently redirect `http://` and `www.` URLs to `https://`? but did not find the answer useful.
The app works properly in every sense except for the redirecting. Here is my app.yaml file:
# [START runtime]
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT myproject.wsgi
runtime_config:
python_version: 3
# [END runtime]
In myproject/settings.py I have these variables defined:
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ('HTTP-X-FORWARDED-PROTO', 'https')
On my local machine, when I set SECURE_SSL_REDIRECT to True, I was redirected to https properly, even though SSL is not supported on localhost. In production, I am still able to access the site using just http.
Is there something I'm missing or doing wrong to cause the redirect not to happen?
Setting secure in app.yaml only works for GAE Standard but not in Flexible. The app.yaml docs for Flexible do not mention this key at all.
You will probably have to do it on application level by inspecting the value of the X-Forwarded-Proto header. It will be set to https if the request to your app came by HTTPS. You can find more info on environment-provided headers in Flexible environment in the docs here.
Make sure you have SecurityMiddleware and CommonMiddleware enabled, and assign a Base_URL:
settings.py:
MIDDLEWARE_CLASSES = (
...
'django.middleware.security.SecurityMiddleware'
'django.middleware.common.CommonMiddleware',
)
BASE_URL = 'https://www.example.com'
Or, you could write your own middleware:
MIDDLEWARE_CLASSES = (
...
'core.my_middleware.ForceHttps',
)
BASE_URL = 'https://www.example.com'
my_middleware.py:
from django.http import HttpResponsePermanentRedirect
class ForceHttps(object):
def process_request(self, request):
if not (request.META.get('HTTPS') == 'on' and settings. BASE_URL == 'https://' + request.META.get('HTTP_HOST') ):
return HttpResponsePermanentRedirect(settings. BASE_URL + request.META.get('PATH_INFO'))
else:
return None
The issue is the header name. When accessing Django through a WSGI server, you should use the X-Forwarded-Proto header instead of the HTTP_X_FORWARDED_PROTO.
See: Why does django ignore HTTP_X_FORWARDED_PROTO from the wire but not in tests?
I had a similar problem and tried a number changes both in the app.yaml and also in settings.py for a custom domain (with the default ssl cert supplied by GAE).
Through trial and error I found that in settings.py updating the allowed hosts to the appropriate domains had the desired result:
ALLOWED_HOSTS = ['https://{your-project-name}.appspot.com','https://www.yourcustomdomain.com']
Update: I am no longer sure the above is the reason as on a subsequent deploy the above was rejected and I was getting a hosts error. However the redirect is still in place... :(
Before this change I was able to switch between http:// and https:// manually in the address bar now it redirects automaticlly.
In order to make this work both on App Engine Flexible and your local machine when testing, you should set the following in your settings.py
if os.getenv('GAE_INSTANCE'):
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
else:
# Running on your local machine
SECURE_SSL_REDIRECT = False
SECURE_PROXY_SSL_HEADER = None
That should be all you need to do to ensure that redirect is happening properly when you are on app engine.
NOTE: If you are using old school app engine cron jobs (via cron.yaml) then you will need to start using the much improved cloud scheduler instead. App engine cron jobs do not properly support redirection to HTTPS but you can easily get it working with cloud scheduler.

How to enable CORS in AppRTC?

I have deployed my own apprtc server with collider & turn server configured in Google App engine locally with virtualbox. Everything is working properly but I want to use this apprtc server in my another project that is in anoter IP. So, Apprtc IP and my project IP is different. Now, when I included apprtc.debug.js & appwindow.js files to my project it cannot initialize loadingParams and says this error message "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://<IP OF APPRTC>:8080/params. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)".
However, entering http://<IP OF APPRTC>:8080/params in the browser gives me correct response but not in the project called in appwindow.js .After a bit of googling I added below lines in sendUrlRequest function :
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
xhr.setRequestHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
Now it says "CORS request did not succeed".
How can I make it work? Do I have to enable cors in server side also, if so where and how to do that? Please help me, I'm totally lost here...

Using https as standard with django project

I am learning django and trying to complete my first webapp.
I am using shopify api & boilder plate (starter code) and am having an issue with the final step of auth.
Specifically, the redirect URL -- it's using HTTP:// when it should NOT and I don't know how to change it..
#in my view
def authenticate(request):
shop = request.GET.get('shop')
print('shop:', shop)
if shop:
scope = settings.SHOPIFY_API_SCOPE
redirect_uri = request.build_absolute_uri(reverse('shopify_app_finalize')) #try this with new store url?
print('redirect url', redirect_uri) # this equals http://myherokuapp.com/login/finalize/
permission_url = shopify.Session(shop.strip()).create_permission_url(scope, redirect_uri)
return redirect(permission_url)
return redirect(_return_address(request))
Which is a problem because my app uses the Embedded Shopify SDK which causes this error to occur at the point of this request
Refused to frame 'http://my.herokuapp.com/' because it violates the following Content Security Policy directive: "child-src 'self' https://* shopify-pos://*". Note that 'frame-src' was not explicitly set, so 'child-src' is used as a fallback.
How do i change the URL to use HTTPS?
Thank you so much in advance. Please let me know if I can share any other details but my code is practically identical to that starter code
This is what the Django doc says about build_absolute_uri:
Mixing HTTP and HTTPS on the same site is discouraged, therefore
build_absolute_uri() will always generate an absolute URI with the
same scheme the current request has. If you need to redirect users to
HTTPS, it’s best to let your Web server redirect all HTTP traffic to
HTTPS.
So you can do two things:
Make sure your site runs entirely on HTTPS (preferred option): Setup your web server to use HTTPS, see the Heroku documentation on how to do this. Django will automatically use HTTPS for request.build_absolute_uri if the incoming request is on HTTPS.
I'm not sure what gets passed in the shop parameter but if it contains personal data I'd suggest to use HTTPS anyway.
Create the URL yourself:
url = "https://{host}{path}".format(
host = request.get_host(),
path = reverse('shopify_app_finalize'))
But you will still need to configure your server to accept incoming HTTPS requests.

Categories