Flask redirection to https prevents http request to work [duplicate] - flask

This question already has answers here:
Are a WSGI server and HTTP server required to serve a Flask app?
(3 answers)
Closed 4 months ago.
I'm using Flask to deliver maps designed with folium.
I'd like to add a geolocation service, and hence, need to migrate change http to https.
I've found a couple of example pages, and the https page delivery works fine.
But ... my users still try to connect through http requests, and redirection from http to https does not work.
More precisely, i've added this code to handle http to https conversion:
#app.before_request
def before_request():
print ("url", request.url)
if request.url.startswith('http://'):
url = request.url.replace('http://', 'https://', 1)
code = 301
print ("url", request.url)
return redirect(url, code=code)
The server initialization works like that :
context = ssl.SSLContext()
context.load_cert_chain('mycert.pem',
'myprivkey.pem')
app.run(debug=False, host= '0.0.0.0', port=5051, ssl_context=context)
The url gets printed when I call https pages, but never when I call http pages.
Any clue why the https activation prevents http from working ?

Your Flask server is HTTPS only. When a browser sends an HTTP (non-secure) request but server responds with HTTPS related (handshake etc) response, then browsers like Firefox/Chrome will abort the flow and display something like:
The connection was reset
The connection to the server was reset while the page was loading.
Your Flask is SSL enabled, users trying with http:// will not be reach the step you have provisioned to redirect them to https://.
You could put a reverse proxy listening on both HTTP (80) and HTTPS (443) ports, HTTPS listener will be forwarding the requests to Flask, HTTP listener will be doing the redirection to HTTPS.

Related

Receiving webhook over https in django development server tunneled using ngrok

I need to test a payment integration, where the payment service sends a webhook when payment is successful. The url for the webhook must be https://xxx-ngrock.io/paymentNotification. In this case, I cannot change the url to http. My problem is, I cannot receive this webhook because:
In development mode django does not allow traffic over https only over http
I tunnel to my development server using this command ./ngrok http https://localhost:8000 which I guess should forward the https traffic, but I have no way of testing it since the development server does not accept traffic over http in the first place.
Additional comments. Currently the ngrok forwarding map where both traffic from http and https are mapped to the https internal traffic that Django does not support for its development serveer.
ngrok by #inconshreveable (Ctrl+C to quit)
Session Status online
Account JianDk (Plan: Free)
Version 2.3.40
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://3304-94-147-65-45.ngrok.io -> https://localhost:8000
Forwarding https://3304-94-147-65-45.ngrok.io -> https://localhost:8000
Connections ttl opn rt1 rt5 p50 p90
7 0 0.06 0.02 0.00 0.01
HTTP Requests
-------------
GET /favicon.ico
GET /
GET /favicon.ico
GET /
GET /
GET /favicon.ico
GET /
ngrok will provide one http and one https links for you to tunnel your dev server to.
If I have misunderstood your question, please add a comment!

Handshake error in Webservice

Our integration partner was using our Web service with http: 8090 and now we are moving to https: 8443 so they tried to update the WS URL but they are getting "handshake error". They are asking whether they can still use http 8090. If we route any traffic coming from http 8090 to https 8443 in the webserver config, will they still get handshake error?
When you create a redirect, the server sends a HTTP 302 which the client is obligated to follow, which means that they should still get the error. depending on your setup, and config, they may be able to send the request anyway, but if that works, then all your traffic is potentially insecure...

Parsing localhost rest using backbone

I am testing a Rest server using Django Rest Framework. By following the tut from Django Rest website I successfully generated a proper API. But when I try to test with backbone.js to talk locally with that server, it seems fail to communicate together.
The server places at address: http://localhost:8080/users/
The client: http://localhost/client
This is the collection and the view in client
var Users = Backbone.Collection.extend({
url: 'http://localhost:8080/apis/',
});
The network after parsing shows status: canceled and type: pending
I suspect the port different caused the error. Could any point me out the correct way ? Thanks
The browser does not allow you to make POST/PUT ajax requests from localhost(:80) to localhost:8080, because of the Same Origin Policy requirement. In order for the browser to consider two addressed as having same origin, they must have the same protocol (http/https), domain name (localhost) and port number.
You can configure the web server at localhost:80 to proxy requests to localhost:8080. Most web servers support this functionality with a simple configuration change. If you are for instance using apache, see documentation.
Sample Apache proxy config:
ProxyPass /api http://localhost:8080/
ProxyPassReverse /api http://localhost:8080/
After this, you can access an address at localhost:8080/users with localhost/api/users:
var Users = Backbone.Collection.extend({
url: '/api/users',
});

C++ Winsock Determine HTTP or HTTPS

I've just started studying Winsocks and I've a simple question for you: how can I determine if the connection to a server must take place over a HTTP or HTTPS connection?
Let's say I want to connect to randomsite.random, how can I know what kind of connection I need? I know that for HTTP I must connect to port 80, while for HTTPS is needed 443, but how can I determine WHEN is needed a HTTPS connection?
Thank you for the attention!
The same way a web browser decides: Based on the URL you are trying to load. In a web browser, the URL begins with http or https, which is used to determine whether an SSL connection should be used. This is also used to determine the port if no port number is specified in the URL.
Many sites offer both a secure and a non-secure version. Some offer only a secure version, but still run a non-secure server which issues a redirect to the URL of the secure version. If you implement following of redirects, you don't need to worry about which version to use: it will happen automatically.
This is usually a function of the site you are connecting to.
If the site requires a HTTPS connection, then if you connect over HTTP you will get a redirect response code with a HTTPS URL.
Firstly, it's not always port 80 and port 443. Secondly, you won't establish successful communication if you use the wrong communication protocol. As said in another answer, if you try to connect via HTTP to an HTTPS server, it will give you a redirect response code with an HTTPS URL.
Most of the time, you have this information before-hand!

Django Socketio Nginx proxy & session cookie issue

I have followed this tutorial: http://www.stephendiehl.com/?p=309 describing how to run a gevent pywsgi server serving Django with socketio behind a nginx front-end.
As this tutorial says, Nginx doesn't support websocket unless using a tcp proxy module. This proxy module doesn't support the use of the same port for socketio and classic serving, from what I understood the configuration look like that:
nginx listen on port 80
nginx tcp proxy listen on port 7000
Everything is forwarded to port 8000
Problem: the resulting socketio request doesn't include the django cookie containing the session id so I have no information on the requesting user in my django view.
I guess it's caused by the fact that the request is made to another port (7000) causing the browser to identify the request as cross-domain ?
What would be the cleanest way to include the django cookie into the request ?
Most answers in this question seem to indicate that port doesn't matter.
Also checked and supposedly WebSockets is regarded as HTTP, so HTTPOnly cookies should still be sent.
SocketIO seems to be using a custom Session manager to track users. Maybe try and link that up?