`我在 Django 项目中遇到用户身份验证问题。我有一个针对医生的自定义用户模型
Doctor
,它继承自 AbstractUser
。尽管在登录时输入了正确的电子邮件和密码,系统仍返回“密码无效”错误。
基础/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser, Group, Permission
class Doctor(AbstractUser):
id = models.AutoField(primary_key=True)
username = models.CharField(max_length=50)
name = models.CharField(max_length=50)
profession = models.CharField(max_length=50, default='Doctor')
email = models.EmailField(max_length=254, unique=True)
emp_code = models.CharField(max_length=50)
password = models.TextField(max_length=150)
USERNAME_FIELD = 'email'
groups = models.ManyToManyField(
Group,
blank=True,
related_name='doctor_group'
)
user_permissions = models.ManyToManyField(
Permission,
blank=True,
related_name='doctor_user_permission'
)
def __str__(self):
return self.username
基础/views.py
def docter_login(request):
if request.method == 'POST':
email = request.POST.get('email').lower()
password = request.POST.get('password')
print(email,password)
# Authenticate the user using the email and password provided in the form
if not Doctor.objects.filter(email__iexact=email).exists():
messages.error(request, 'User with that email Does not exists.')
return render(request, 'base/error.html')
user = authenticate(request, email=email, password=password)
if user is not None and user.is_doctor:
login(request, user)
return redirect('home')
else:
messages.error(request,'Invalid password.')
return render(request, 'base/error.html')
return render(request, 'base/doctor_login.html')
用户存在并传递正确的凭据进行身份验证,但它仍然返回“无效密码”。什么可能导致此问题? `
authenticate
不起作用,因为默认情况下它会使用 username
标识用户,并且也不执行 __iexact
查找。
我们可以编写自定义身份验证后端 [Django-doc]来处理电子邮件:
# app_name/authentication.py
from django.contrib.auth.backends import BaseBackend
class EmailAuthenticationBackend(BaseBackend):
def authenticate(self, request, email=None, password=None):
try:
user = Doctor.objects.get(email__iexact=email, is_active=True)
except User.DoesNotExist:
return None
if user.check_password(password):
return user
return None
AUTHENTICATION_BACKENDS
设置[Django-doc]:
# settings.py
# …
AUTHENTICATION_BACKENDS = ['app_name.authentication.EmailAuthenticationBackend']
请注意,当您注册用户时,您应该使用
Doctor.objects.create_user(…)
。我也不会说没有具有该特定用户名的用户,因为这样人们就可以猜测是否某个电子邮件地址已注册为用户:只需给出用户名/密码组合无效的错误,您就可以不要公开有关哪些电子邮件地址已注册用户以及哪些电子邮件地址未注册的信息。