Rolling your own authentication in Django

For various reasons I wanted to see just what was required to roll my own basic authentication using Django. I am aware there’s a built-in authentication module, django.contrib.auth, but it’s overkill for my ultimate goal and it depends on the session module in ways that only further study can reveal. I heard rumours that the authentication module would be pluggable. The only pluggable aspect of it that I found was the backend (i.e. the data model).

In the end the most relevant reason for doing this was that I wanted to :-)

So, what’s involved in it? It turns out, not much!

First I created a middleware class that extracts the authentication credentials (read username and password) and sticks a ‘user object’ in the request depending on just how successfully it does this:

from base64 import b64decode
from models import User, AnonUser, BadUser

class MiniAuthMiddleWare(object):
    def process_request(self, request):
        auth = request.META.get('Authorization', '') or \
                request.META.get('HTTP_AUTHORIZATION', '')
        if not auth:
            request.user = AnonUser()

        name, pwd = b64decode(auth[6:]).split(':')
            u = User.objects.get(name=name)
            if pwd != u.passwd:
                request.user = BadUser()
            request.user = u
        except User.DoesNotExist, e:
            request.user = BadUser()
        except AssertionError, e:
            request.user = BadUser()


The model related to this is rather minimal:

from django.db import models

class User(models.Model):
    name = models.CharField(maxlength=50, primary_key=True)
    passwd = models.CharField(maxlength=50)

    def is_authenticated(self):
        return True

class AnonUser:
    name = 'Anonymous'
    passwd = 'NoPass'

    def is_authenticated(self):
        return False

class BadUser:
    name = 'BadUser'
    passwd = 'NoPass'

    def is_authenticated(self):
        return False

Then I decorated the functions/urls that required authentication with the following:

def _RequireAuthorization(func):
    def _wrapper(request):
        if not request.user.is_authenticated():
            response = HttpResponse()
            response.status_code = 401
            response['WWW-Authenticate'] = 'Basic Realm="Silly Realm"'
            return response
            return func(request)
    return _wrapper

That all seems to work just fine :-)

Hugh Bien

Nice. For a few of my projects, I decided to roll my own authentication too. Here’s another quick walkthrough on [how to write your own authentication system for Django] (

Steve Achabal

Thanks for this blog. I am new at django and this will be a big help.

Leave a comment