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.
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
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.
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