django authentication without a password

voodoogiant picture voodoogiant · Jul 3, 2011 · Viewed 15k times · Source

I'm using the default authentication system with django, but I've added on an OpenID library, where I can authenticate users via OpenID. What I'd like to do is log them in, but it seems using the default django auth system, I need their password to authenticate the user. Is there a way to get around this without actually using their password?

I'd like to do something like this...

user = ... # queried the user based on the OpenID response
user = authenticate(user) # function actually requires a username and password
login(user)

I sooner just leave off the authenticate function, but it attaches a backend field, which is required by login.

Answer

Wilfred Hughes picture Wilfred Hughes · Jan 21, 2014

It's straightforward to write a custom authentication backend for this. If you create yourapp/auth_backend.py with the following contents:

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User


class PasswordlessAuthBackend(ModelBackend):
    """Log in to Django without providing a password.

    """
    def authenticate(self, username=None):
        try:
            return User.objects.get(username=username)
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Then add to your settings.py:

AUTHENTICATION_BACKENDS = (
    # ... your other backends
    'yourapp.auth_backend.PasswordlessAuthBackend',
)

In your view, you can now call authenticate without a password:

user = authenticate(username=user.username)
login(request, user)