英文:
Django Authentication to use both email and username in exiting app
问题
我在现有应用程序中添加自定义AUTHENTICATION_BACKENDS方面遇到了困难。我已经完成了我的应用程序,但现在希望能够使用用户名或电子邮件ID进行登录。我已经成功地能够使用用户名和密码进行登录。现在我想添加电子邮件ID。
我尝试在我的settings.py中添加以下代码:
AUTHENTICATION_BACKENDS = (
'authentication.backends.EmailOrUsernameModelBackend',
'django.contrib.auth.backends.ModelBackend',
)
在authentication/backends.py中,我有以下代码:
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
我的authentication/views.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})
我尝试在EmailOrUsernameModelBackend的authenticate方法中打印一些语句,但没有输出,所以我猜想由于某种原因它没有调用该方法。
请帮助我弄清楚我漏掉了什么,以便调用自定义authenticate方法。
英文:
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 \authentication\backends.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 \authentication\views.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.
答案1
得分: 0
我认为问题在于您没有从Django中的BaseBackend
进行子类化,而只是从常规的Python object
进行子类化。
通常我会创建两个独立的后端,这样我的代码对其他人来说更容易阅读。
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 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论