Login

Enforce site wide login

Author:
chbrown
Posted:
October 27, 2008
Language:
Python
Version:
1.0
Score:
6 (after 8 ratings)

This is based on a snippet contributed by zbyte64 ( RequireLoginMiddleware) but turned on its head. RequireLoginMiddleware enforces authentication for a subset of urls defined in settings.py. This middleware requires authentication for all urls except those defined in settings.py. The aim is to globally enforce site wide authentication without having to decorate individual views.

To use, add the class to MIDDLEWARE_CLASSES and then define the urls you don't need authentication for. These go in a tuple called PUBLIC_URLS in settings.py. For example:-

PUBLIC_URLS = (
    r'project/application/login/',
    r'project/application/signup/',
)

By default, authentication is not required for any urls served statically by Django. If you want to subject these to the same validation, add an entry to settings.py called SERVE_STATIC_TO_PUBLIC with a value of True.

 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
37
38
39
40
41
42
from django.http import HttpResponseRedirect
from django.conf import settings
import re

class EnforceLoginMiddleware(object):
    """
    Middlware class which requires the user to be authenticated for all urls except 
    those defined in PUBLIC_URLS in settings.py. PUBLIC_URLS should be a tuple of regular 
    expresssions for the urls you want anonymous users to have access to. If PUBLIC_URLS 
    is not defined, it falls back to LOGIN_URL or failing that '/accounts/login/'.  
    Requests for urls not matching PUBLIC_URLS get redirected to LOGIN_URL with next set 
    to original path of the unauthenticted request. 
    Any urls statically served by django are excluded from this check. To enforce the same
    validation on these set SERVE_STATIC_TO_PUBLIC to False.
    """

    def __init__(self):
        self.login_url   = getattr(settings, 'LOGIN_URL', '/accounts/login/' )
        if hasattr(settings,'PUBLIC_URLS'):
            public_urls = [re.compile(url) for url in settings.PUBLIC_URLS]
        else:
            public_urls = [(re.compile("^%s$" % ( self.login_url[1:] )))]
        if getattr(settings, 'SERVE_STATIC_TO_PUBLIC', True ):
            root_urlconf = __import__(settings.ROOT_URLCONF)
            public_urls.extend([ re.compile(url.regex) 
                for url in root_urlconf.urls.urlpatterns 
                if url.__dict__.get('_callback_str') == 'django.views.static.serve' 
            ])
        self.public_urls = tuple(public_urls)

    def process_request(self, request):
        """
        Redirect anonymous users to login_url from non public urls
        """
        try:
            if request.user.is_anonymous():
                for url in self.public_urls:
                    if url.match(request.path[1:]):
                        return None
                return HttpResponseRedirect("%s?next=%s" % (self.login_url, request.path))
        except AttributeError:
            return HttpResponseRedirect("%s?next=%s" % (self.login_url, request.path))

More like this

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

Comments

maggon (on April 1, 2009):

We should add the following patch to pass through url parameters.

query_string = request.META["QUERY_STRING"] if query_string: url = "%s?%s" % (request.path, query_string)

#

[email protected] (on May 15, 2012):

I used the above snippet for enforcing site wide login required. I am facing an issue here. I successfully login into the system and get redirected to /app/home/ page. I navigate to /app/profile/ and clear the cache, not when I click some links, I get redirected to the login page but when I login, it doesn't redirect to /app/profile/. Instead it goes to /app/home/. Please let me know how can I achieve this.

#

Please login first before commenting.