Django Authentication to use both email and username in exiting app

Question:

I am struggling with adding custom AUTHENTICATION_BACKENDS for my exiting app. I have all done with my app but now want to login with username or EmailID. I am successfully able to login with username and password.
now just want to add EmailID as well.

I tried adding below code in my settings.py
AUTHENTICATION_BACKENDS = ( 'authentication.backends.EmailOrUsernameModelBackend', 'django.contrib.auth.backends.ModelBackend', )

and in authenticationbackends.py I have

from django.conf import settings
from django.contrib.auth.models import User

class EmailOrUsernameModelBackend(object):
    def authenticate(self, username=None, password=None):
        print("Inside EmailorUsernameModelBackend")
        if '@' in username:
            print("User with Email")
            kwargs = {'email': username}
        else:
            print("User with Username")
            kwargs = {'username': username}
        try:
            user = User.objects.get(**kwargs)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

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

where my authenticationviews.py

def login_view(request):
    form = LoginForm(request.POST or None)

    msg = None

    if request.method == "POST":

        if form.is_valid():
            username = form.cleaned_data.get("username")
            password = form.cleaned_data.get("password")
            user = authenticate(username=username, password=password)
            print("User=",user)
            if user is not None:
                login(request, user)
                return redirect("dashboard")
            else:
                msg = 'Invalid credentials'
        else:
            msg = 'Error validating the form'

    return render(request, "/login.html", {"form": form, "msg": msg})

I am trying to print some statement if authenticate method call from EmailOrUsernameModelBackend but none printing, so I guess for some reason it is not calling that method.

please help me what I am missing to call custom authenticate method.

Asked By: PTB

||

Answers:

I think the issue is that you’re not subclassing BaseBackend from Django, but just the regular python object.
I usually do 2 seperate backends, that makes my code a lot clearer to read for others.

from django.contrib.auth.backends import BaseBackend

class EmailBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None):
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None


class UsernameBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None):
        try:
            user = User.objects.get(username=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

Answered By: user20223018
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.