Django allows you to authenticate against different sources. The AUTHENTICATION_BACKENDS
setting includes the list of authentication backends for your project. By default, this setting is set to the following:
('django.contrib.auth.backends.ModelBackend',)
The default ModelBackend
authenticates users against the database using the User
model of django.contrib.auth
. This will suit most of your projects. However, you can create custom backends to authenticate your user against other sources like a LDAP directory or any other system.
You can read more information about customizing authentication at https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#other-authentication-sources.
Whenever you use the authenticate()
function of django.contrib.auth
, Django tries to authenticate the user against each of the backends defined in AUTHENTICATION_BACKENDS
one by one, until one of them successfully authenticates the user. Only if all of the backends fail to authenticate the user, he or she will not be authenticated into your site.
Django provides a simple way to define your own authentication backends. An authentication backend is a class that provides the following two methods:
Creating a custom authentication backend is as simple as writing a Python class that implements both methods. We are going to create an authentication backend to let users authenticate in our site using their e-mail address instead of their username.
Create a new file inside your account
application directory and name it authentication.py
. Add the following code to it:
from django.contrib.auth.models import User class EmailAuthBackend(object): """ Authenticate using e-mail account. """ def authenticate(self, 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
This is a simple authentication backend. The authenticate()
method receives the username
and password
optional parameters. We could use different parameters, but we use username
and password
to make our backend work with the authentication framework views straightaway. The preceding code works as follows:
authenticate()
: We try to retrieve a user with the given e-mail address and check the password using the built-in check_password()
method of the User
model. This method handles the password hashing to compare the given password against the password stored in the database.get_user()
: We get a user by the ID set in the user_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', )
We keep the default ModelBackend
that is used to authenticate with username and password, and we include our own email-based authentication backend. Now, open http://127.0.0.1:8000/account/login/
in your browser. Remember that Django will try to authenticate the user against each of the backends, so now you should be able to log in using your username or e-mail account seamlessly.