One smaller feature we added in our last system update was the ability to force HTTPS without needing to change your code. Here's a bit more information about why you might want to do that, and how it works.
If you're using your default yourusername
.pythonanywhere.com website on PythonAnywhere, people can access it using a non-secure connection via
http://yourusername.pythonanywhere.com, or using a secure connection via
https://yourusername.pythonanywhere.com. Likewise, if you have a paid account and are using a custom domain, they can access it non-securely via
http://www.yourdomain.com or -- if you've set up an HTTPS certificate -- they can access it securely via
Having two ways to access the site is fine, but these days there's a general move across the Internet to using HTTPS for everything. Newer versions of Chrome explicitly put the words "Not secure" in the browser's address bar when you access a non-HTTPS site, and Google also apparently rank HTTPS sites higher in search results.
So often, what you want to do is set things up so that people can only use HTTPS to access your site -- never simple non-secure HTTP. This is called "forcing HTTPS", and works by sending back a redirect when people try to access the non-secure URL. So if someone goes to
http://www.yourdomain.com, they're just bounced straight over to
https://www.yourdomain.com, and likewise if they go to
http://www.yourdomain.com/something they're redirected to
Because forcing HTTPS is a common requirement, most of the main Python web frameworks have support for it build in -- Django has a
SECURE_SSL_REDIRECT setting, for example, and there's a Flask extension called
flask-sslify. In the past, we suggested that people add the appropriate configuration to their code to use those features, and it all worked fine.
There were just two problems:
We made a bunch of changes to the way our loadbalancers work as part of our recent system update, primarily in order to improve the way we handle HTTPS certificates. Because we were working in that part of the code, it was easy for us to add the capability to force HTTPS to our own infrastructure. So now, in order to force HTTPS for your website, just go to the "Web" page inside PythonAnywhere, select the site on the left, scroll down to the "Security" section, and toggle it on:
You'll need to reload the site using the button at the top of the page to activate it.
There are a couple of things to keep in mind when using this feature.
POSTed data. This means that we can't do a force-HTTPS redirect in response to a POST request, because the data would get lost. (It also wouldn't be super-valuable -- if the user has POSTed data, then it's already gone across the Internet unencrypted, so sending it again in encrypted form wouldn't really help matters.)
Hopefully that was all pretty clear, but if you do have any questions, just drop us a line at email@example.com or leave a comment below.