简体   繁体   中英

How to use django-sslify to force https on my Django+nginx+gunicorn web app, and rely on Cloudflare's new free SSL?

Intro

Cloudflare's providing SSL for free now, and I would be a fool to not take advantage of this on my site, and a downright dickhead to break everything in the process of trying to.

I can code apps just fine, but when it comes to setting up or configuring https/nginx/gunicorn/etc/idon'tknowtheterminology, I know barely enough to follow Googled instructions.

Question

I would like to use django-sslify to force https on my Django web app. How may I achieve this without upsetting the balance in my life , given the following known facts?

Known facts

  1. I'm using Django 1.7, running on a DigitalOcean server hooked up to a (free) Cloudflare DNS. Django is fitted (served?) with nginx and gunicorn. Basically followed this guide to get it all set up.
  2. Accessing my website currently defaults to a regular http://example.com header.
  3. Manually accessing https://example.com works with the green lock and all, but this breaks all form submissions with the error "(403) CSRF verification failed. Request aborted.".
  4. In my Cloudflare site settings, the domain is currently configured to "Flexible SSL".
  5. Trying to use django-sslify with my existing setup totally breaks everything, and the browser is unable to return a response.
  6. This info nugget tells me that I should use the "Full SSL" configuration setting when using django-sslify with Cloudflare's SSL.
  7. Cause for hesitation found here where it is mentioned that a $20/mo Pro Cloudflare account is needed to handle SSL termination. So I really don't want to screw this up :/
  8. There was only 1 mention of "http" or "https" anywhere in my nginx and gunicorn configuration, specifically in my nginx config:

location / { proxy_pass http://127.0.0.1:8001; ... } proxy_pass http://127.0.0.1:8001; ... }

Ok I think that's all I have

Also, my server is providing an Django Rest Framework api for a Phonegap app, does that need to be taken in to consideration? If I need to provide addtional information do let me know and I'll get back to you. Thank you for taking a look at this! :)

CloudFlare allows you to enable specific page rules , one of which is to force SSL (by doing a hard redirect ). This is a great thing to use in addition to django-sslify or django-secure


In addition to setting up your SSL redirect, you also need to tell Django to handle secure requests. Luckily, Django provides a decent guide for doing this, but there are a few things that it doesn't mention but I've had to do with nginx.

In your Django settings, you need to tell Django how to detect a secure request

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')

In your nginx configuration you need to set up the X-Forwarded-Protocol header (and the X-Forwarded-For / X-Scheme headers are also useful).

proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

You also need to proxy the Host header down, so Django is able to read the correct host and port, which is used in generating absolute urls and CSRF, among other things.

proxy_set_header Host $http_host;

Note that I used the $http_host variable instead of $host or $host:$server_port . This will ensure that Django will still respect CSRF requests on non-standard ports, while still giving you the correct absolute urls.

As with most things related to nginx and gunicorn, YMMV and it gets easier after you do it a few times.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM