Skip to content

Instantly share code, notes, and snippets.

@tomleo
Created January 17, 2023 20:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomleo/eedd988750a680b3f25e426c5fc3574a to your computer and use it in GitHub Desktop.
Save tomleo/eedd988750a680b3f25e426c5fc3574a to your computer and use it in GitHub Desktop.
Email Login w/ Django

Login Users with Email

A response to: Django: How to Log Users In With Their Email

There's an easier way than creating a custom user type. All you need to change is the AUTHENTICATION_BACKENDS setting!

See the example account app files in this gist!

Thanks!

-- Tom

# accounts/backends.py
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
UserModel = get_user_model()
class AccountModelBackend(ModelBackend):
"""
Tweaked ModelBackend so that users can be authenticated
by passing in their email instead of username
"""
def authenticate(self, request, email=None, password=None, **kwargs):
if email is None or password is None:
return
try:
user = UserModel._default_manager.get(email=email)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
# accounts/controllers.py
from account.exceptions import InvalidCredentialsException
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import UserManager
from django.contrib.auth import authenticate, login as contrib_login
def login(email, password, request):
normalized_email = UserManager.normalize_email(email)
user = authenticate(email=normalized_email, password=password)
if not user:
raise InvalidCredentialsException()
else:
contrib_login(request, user)
return user
# accounts/exceptions.py
class InvalidCredentialsException(Exception):
pass
AUTHENTICATION_BACKENDS = (
'account.backends.AccountModelBackend',
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment