Django login using email
Using an email address rather than username for logging in to a Django application.
Django auth login views
Building the new Matchstaff jobsite for European Bartender School, I wanted to be able to login users using their email address (rather than their username which is the Django default way).
Django already provides views for logging in and out, so rather than reinvent the wheel we use those. Those use the templates from the Django admin by default, but we want to use the custom templates from our designer. This is easy enough, by passing the template_name argument to the view.
in urls.py we add the following lines for login and logout views
from django.contrib import admin, auth
urlpatterns = [
...
...
url(r'^login/$', auth.views.login, {'template_name': 'jobsite/login.html'} , name='login'),
url(r'^logout/$', auth.views.logout , {'template_name': 'jobsite/logout.html'}, name='logout'),
..
]
writing a custom authentication backend
I created a file backends.py and added the following to it. This is where Django hooks in and uses our new class / function to check the email for logging in.
ModelBackend is the default Django authentication backend, so we subclass that, and override the authenticate method.
from django.contrib.auth.hashers import check_password
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
class UserModelEmailBackend(ModelBackend):
def authenticate(self, username="", password="", **kwargs):
try:
user = get_user_model().objects.get(email__iexact=username)
if check_password(password, user.password):
return user
else:
return None
except get_user_model().DoesNotExist:
# No user was found, return None - triggers default login failed
return None
In addition to that we need to tell Django to use the new UserModelEmailBackend that we have created.
In settings.py I added the following:
AUTHENTICATION_BACKENDS =['jobsite.backends.UserModelEmailBackend' ,
'django.contrib.auth.backends.ModelBackend']