4

I have SSL certification at the ELB level for my site hosted on Amazon. I used the following site to setup a middle ware to forward all http requests to https:

http://djangosnippets.org/snippets/2472/

It's working great. But here's my question. EACH request is getting forwarded, so I notice a slight lag when clicking links, etc. Nothing extreme. But is there a way to force django to do everything via https? When I have code to HttpResponse and HttpResponseRedirect, how can I have it default to https instead of http? I tried to search for this and was unsuccessful...

I know it's possible if I type https://www... for each URL for redirect and on the links for the pages, but I wanted to avoid doing it that way if possible.

KVISH
  • 12,923
  • 17
  • 86
  • 162
  • there's a proper way for building URLs correctly in Django these days that means not having to rely on middleware or web server configuration to redirect on every click. See my response below - it builds the URLs using the correct protocol in the first place. – lukewarm Nov 09 '17 at 23:10

3 Answers3

2

Looking at the middleware you posted, it is doing exactly what you mentioned you did not want to manually do i.e append https to every incoming http request from your domain. I would recommend you offload this job to the front-end server (Either nginx or apache) .

Example with

Community
  • 1
  • 1
Pratik Mandrekar
  • 9,362
  • 4
  • 45
  • 65
2

When Django builds absolute URIs to redirect to, it checks request.is_secure to decide what protocol scheme it should be using (http, https, or ftp).

Django defaults to doing this based on the protocol used for the request, but as you've identified, when behind an LB or proxy this can be wrong due to SSL termination at the LB/proxy level.

You can configure Django to detect this exact scenario using the SECURE_PROXY_SSL_HEADER setting.

lukewarm
  • 839
  • 6
  • 14
1

We use Nginx currently to load balance, force SSL on requests, and terminate SSL connections as they are proxied to internal app servers. It doesn't have as fancy load balancing capabilities, but Nginx is small and fast enough to put anywhere.

Here's the code bits you may need:

# listen on port 80 and redirect to SSL.
server {
   listen         80;
   server_name    site.com;
   rewrite        ^ https://$server_name$request_uri? permanent;
}

# listen on port 443, terminate SSL, and proxy to internal web app
# can be node, rails, whatever.
server {
  listen 443;
  server_name  site.com;
  gzip  on;
  client_max_body_size 250M;

  ssl   on;
  ssl_certificate   /etc/nginx/site.com.crt;
  ssl_certificate_key  /etc/nginx/site.com.key;
  keepalive_timeout  70;

  location / {
    proxy_pass http://127.0.0.1:8080;
    # We add this extra header just so proxied web app
    # knows this used to be an SSL connection.
    proxy_set_header x-https 1;
    include /etc/nginx/conf.d/proxy.conf;
  }
}
Mauvis Ledford
  • 40,827
  • 17
  • 81
  • 86