Login

HTTPS redirections middleware with updated URL template tag

Author:
xlq
Posted:
October 19, 2012
Language:
Python
Version:
1.4
Score:
0 (after 0 ratings)

This middleware redirects HTTP requests to HTTPS for some specified URLs, in the same way as 85. It also changes the url template tag to use the https scheme for the same URLs. For example, if you have the following URL pattern:

url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'https': True})

then the template:

{% from future import url %}
{% url 'django.contrib.auth.views.login' %}

will render:

https://host.example.com/accounts/login/

and any plain HTTP requests to /accounts/login get redirected to HTTPS. URL patterns not marked with 'https': True remain unaffected.

Notes:

  • The HttpRequest object must be present in the template context as request, so add django.core.context_processors.request to TEMPLATE_CONTEXT_PROCESSORS and make sure to use RequestContext.

  • This snippet overrides the existing url template tag. Remove the last line and register the new url function properly, as a separate tag, if this makes you unhappy. You'd then have to change your templates to use it.

  • It would be nicer to change the way reverse look-ups behave instead of changing only the url template tag, but the URL resolver, and the reverse function, know nothing about requests, so have no way to find the correct host name.

 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
from django.http import HttpResponsePermanentRedirect
from django.template import Library
from django.template.base import Node
import django.templatetags.future
from django.core import urlresolvers

class HttpsUrls(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        https_wanted = view_kwargs.pop("https", False)
        if request.method == "GET" \
        and https_wanted \
        and not request.is_secure():
            return HttpResponsePermanentRedirect \
                ("https://%s%s" % (request.get_host(), request.get_full_path()))

class HttpsUrlNode(Node):
    def __init__(self, url_node):
        self.url_node = url_node

    def render(self, context):
        url_string = self.url_node.render(context)
        match = urlresolvers.resolve(url_string)
        if match.kwargs.get("https", False):
            url_string = "https://%s%s" % (context["request"].get_host(), url_string)
        return url_string

def url(parser, token):
    return HttpsUrlNode(django.templatetags.future.url(parser, token))
django.templatetags.future.register.tag(url)

More like this

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

Comments

Please login first before commenting.