Login

SSL Middleware for Webfaction

Author:
parlar
Posted:
May 16, 2007
Language:
Python
Version:
.96
Score:
6 (after 6 ratings)

NOTE Stephen updated his original snippet http://www.djangosnippets.org/snippets/85/ to work with WebFaction, please use his version now

This code is 95% from Stephen Zabel's snippet at http://www.djangosnippets.org/snippets/85/. However, his snippet, as it was, wouldn't work when enabling SSL for the admin site on Webfaction. For some reason, the default request.is_secure() doesn't behave properly with Webfaction's setup and redirects.

One thing Webfaction does do is add X-Forwarded-ssl='on' to any https requests. So instead of using request.is_secure(), I've just used that.

To setup the admin site with SSL on Webfaction, do the following:

  1. Install this middleware wherever you like, and add it to settings.py
  2. In your Webfaction panel, create your 'django' application ("application" in the Webfaction sense, not the Django sense)
  3. Create two sites. The first, your main site (which I'll call example.com), should use the application 'django' mounted at '/'. Do not have HTTPS enabled on this site.
  4. For the second site, also use the application 'django', and again mount it to '/', but this time enable HTTPS.
  5. In your urls.py, modify the admin URL as follows: (r'^admin/', include('django.contrib.admin.urls'), {'SSL':True} )

That should be it! The admin section of the site now requires SSL (as specified in urls.py), and if anyone tries to access the admin via regular http, a redirect to https will occur.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
__license__ = "Python"
__copyright__ = "Copyright (C) 2007, Stephen Zabel, Jay Parlar"
__author__ = "Stephen Zabel - [email protected]"
__contributors__ = "Jay Parlar - [email protected]"

from django.conf import settings
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect, get_host

SSL = 'SSL'

def is_secure(request):
    if 'HTTP_X_FORWARDED_SSL' in request.META:
        return request.META['HTTP_X_FORWARDED_SSL'] == 'on'
    return False

class SSLRedirect:
    def process_view(self, request, view_func, view_args, view_kwargs):
        if SSL in view_kwargs:
            secure = view_kwargs[SSL]
            del view_kwargs[SSL]
        else:
            secure = False

        if not secure == is_secure(request):
            return self._redirect(request, secure)

    def _redirect(self, request, secure):
        protocol = secure and "https" or "http"
        newurl = "%s://%s%s" % (protocol,get_host(request),request.get_full_path())
        if settings.DEBUG and request.method == 'POST':
            raise RuntimeError, \
"""Django can't perform a SSL redirect while maintaining POST data.
Please structure your views so that redirects only occur during GETs."""

        #return HttpResponseRedirect(newurl)
        return HttpResponsePermanentRedirect(newurl) #I have not had time to test this, but it appears to work better.

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

sjzabel (on July 3, 2007):

Hey this is great. I modified it just slightly? What I would like to propose is that we check request.is_secure() in your is_secure() If that comes back as false then we use your test for the webfaction header. I think that having a single option for the end user that works in both cases is prolly a better solution.

If you have a chance... could you try out my change to the SSL Middleware code in your environment to make sure that it works correctly?

Thanks, Stephen

#

chrj (on July 4, 2007):

Wouldn't it make more sense to do this with a decorator? Either way it would be easy to add a decorator "frontend" to your middleware - and a nice feature :-)

#

sjzabel (on July 25, 2007):

Sorry to comment back so late... I actually originally wrote it as a decorator. but then I was left with having to add an @ssl and @notssl decorator to every action. Add in some @login_required and various permission decorators and it got messy vary fast.

IMO it also just "feels" like a better place to put it.

#

hal (on November 18, 2008):

SMALL UPDATE:

change : 'if not secure == is_secure(request):' to: 'if not secure == self._is_secure(request) and secure != 'keep':'

It will keep your current protocol, if you use 'keep' in view args.

#

spookylukey (on August 28, 2009):

I think it would be much better to create a separate middleware for WebFaction which fixes the request object so that HttpRequest.is_secure() actually works. There are other places in Django that might rely on HttpRequest.is_secure() returning a correct value. I'll see if I can hack up a solution for this.

#

kimyung (on April 17, 2014):

wow thanks its very help me Cream Pemutih Wajah Pemutih Wajah Alami Cream Pemutih Wajah Yang Aman

#

kimyung (on April 17, 2014):

great i love this Cara Cepat Hamil

#

Please login first before commenting.