Enforce HTTPS for authenticated users but HTTP for anonymous

40 views
Skip to first unread message

Roarster

unread,
Nov 29, 2012, 4:32:28 AM11/29/12
to django...@googlegroups.com
Is there any easy way to have a django site enforce HTTPS for authenticated users while any anonymous users would default to HTTP?  This would allow me to protect the sessions and cookies for users who have logged on while conserving server resources for those who aren't authenticated (I would assume the majority of connections).  As part of this it would also make sense for me to ensure the login and register pages also use HTTPS to protect any passwords.

I'm not sure if it's relevant but I'm using Nginx as a web server with uwsgi dealing with the django requests.

Thanks.

kahara

unread,
Nov 29, 2012, 5:47:14 AM11/29/12
to django...@googlegroups.com
Could this be achieved, in a view, by quering if the user is logged in and if so, redirecting to the same page but with HTTPS? Something like:

def index(request):
  if request.user.is_authenticated() and not request.is_secure():
    # redirect to HTTPS

One could argue though that to keep things as simple and robust as possible, running everything over HTTPS would be a better choice. Is HTTPS that much more compute intensive with your traffic?


    J

Tom Evans

unread,
Nov 29, 2012, 6:10:22 AM11/29/12
to django...@googlegroups.com
Write some custom middleware to handle your logic. We have a similar
requirement at $JOB - SSL on logins, preference pages, anything with a
password form on it, but not on other views. I can't show the code,
but I can describe the logic.

You actually need to specify two things for a URL - is SSL allowed,
and is SSL required.
Your middleware should hook in to process_request.
If the current request is not SSL, check if the URL requires SSL and
redirect to SSL if it does.
If the current request is SSL, check if SSL is allowed, redirect to
non SSL if it doesn't.
If the request is a POST and needs redirection, blow up, this is a
logic error (you can't redirect a POST, and anything requiring this is
doing things in an incorrect order).

There is an easy way to check if SSL is required for a view. In your
urlconf, you can specify additional keyword arguments for a view. Our
middleware checks for the keyword arguments 'ssl_required' and
'ssl_allowed', which neatly allows the configuration for whether a URL
is to be handled by SSL to be included along with all the other URL
configuration.

An important note is that the middleware must remove these additional
arguments, since the views will not be expecting them!

Cheers

Tom

Roarster

unread,
Nov 29, 2012, 6:15:56 AM11/29/12
to django...@googlegroups.com
Possibly, but I guess this would involve updating all of my views?

As for performance, I'm not sure yet since we haven't launched.  I'm really just thinking about things that might keep costs down - particularly if it's easy to do.  If any solution is complicated or messy then I probably will just go with HTTPS for everything.

Roarster

unread,
Nov 29, 2012, 6:30:54 AM11/29/12
to django...@googlegroups.com, teva...@googlemail.com
Tom, that sounds like a very clean approach.  I haven't really done any middleware development yet but looking at the documentation it sounds like this shouldn't be that complicated so I might give it a bash.  Does it cause any issues if an authenticated user is redirected to HTTPS?  I assume the cookie is still sent to the server and they remain authenticated?
Reply all
Reply to author
Forward
0 new messages