1đź‘Ť
This code is taken from the book “Django 3 by Example”, chapter 4, section “Building a custom authentication backend”.
Django provides a simple way to define your own authentication backends. An authentication backend is a class that provides the following two methods: authenticate()
and get_user()
.
Suppose you have the account
app in your project to manage the authentication logic. You can create the authentication.py
file with the following code:
class EmailAuthBackend(object):
"""
Authenticate using an e-mail address.
"""
def authenticate(self, request, username=None, password=None):
try:
user = User.objects.get(email=username)
if user.check_password(password):
return user
return None
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
The preceding code works as follows:
authenticate()
: You try to retrieve a user with the given email address and check the password using the built-incheck_password()
method of the user model. This method handles the password hashing to compare the given password with the password stored in the database.get_user()
: You get a user through the ID provided in theuser_id
parameter. Django uses the backend that authenticated the user to retrieve the User object for the duration of the user session.
Edit the settings.py
file of your project and add the following setting:
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'account.authentication.EmailAuthBackend',
]
In the preceding setting, you keep the default ModelBackend
that is used to authenticate with the username and password and include your own email-based authentication backend.
Django will try to authenticate the user against each of the backends, so now you should be able to log in seamlessly using your username or email account. User credentials will be checked using the ModelBackend
authentication backend, and if no user is returned, the credentials will be checked using your custom EmailAuthBackend
backend.