Django сигнал user_login_failed не работает для пользовательской модели пользователя, пользовательский бэкенд
Я начинающий Django и в связи с требованиями моего проекта, я пришел к выводу, что мне нужно реализовать Custom User model, а также в связи с этим я также реализовал Custom Backend. Но, теперь я не могу использовать user_login_failed Django Signal, так как я думаю использовать его для ограничения попытки входа пользователя до 3.
и еще, у меня есть зашифрованный и незашифрованный пароль, и я хочу аутентифицировать оба пока что, но в будущем только зашифрованный пароль останется в моей БД например: - "pbkdf2_sha256$390----------------------------"
Любая помощь будет для меня очень важна. Спасибо
settings.py
AUTH_USER_MODEL = 'accounts.Usermanagement'
AUTHENTICATION_BACKENDS = [
'accounts.backends.EmailAuthBackend',
'django.contrib.auth.backends.ModelBackend',
]
modely.py
class Usermanagement(AbstractBaseUser):
emailid = models.CharField(db_column='EmailID', unique=True, max_length=45,default=1)
------------
---------
-----------
objects = UsermanagementCustomUserManager()
USERNAME_FIELD = "emailid"
EMAIL_FIELD = "emailid"
managers.py
class UsermanagementCustomUserManager(BaseUserManager):
def create_user(self,emailid,firstname, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not emailid:
raise ValueError('Users must have an email address')
user = self.model(
emailid=self.normalize_email(emailid),
password=password,
)
user.set_password(password)
user.save(using=self._db)
return user
backends.py
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.hashers import make_password,check_password
from django.contrib.auth import get_user_model
Usermanagement = get_user_model()
class EmailAuthBackend(BaseBackend):
def authenticate(self,request,username=None,password=None):
# print("Custom authenticate rqst: ",request)
try:
print("Trying the email backend!")
user = Usermanagement.objects.get(emailid=username)
print("Got the user")
# print(password)
# print(user.password)
# print(check_password(password))
# print(user.check_password(password))
if user.password == password or user.check_password(password):
return user
except user.DoesNotExist:
return None
def get_user(self,user_id):
try:
print("Getting the user of the Email Bkacned")
return Usermanagement.objects.get(pk=user_id)
except Usermanagement.DoesNotExist:
return None
views.py
from django.contrib.auth import login,logout ,authenticate
from django.contrib.auth.forms import AuthenticationForm
def loginPage(request):
# POST
if request.method == 'POST':
form = AuthenticationForm(request,data=request.POST)
if form.is_valid():
email = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
#Check
print("EMAIL: ",email)
print("PASSWORD: ",password)
# Authentication USER
user = authenticate(request,username=email,password=password)
print("Authenticated ",user) # Check
# check
print(user)
if user is not None:
if user.is_active:
login(request,user,backend='accounts.backends.EmailAuthBackend')
# messages.info(request, f"You are now logged in as {email}.")
return redirect("home")
else:
pass
else: # If User Not found
# messages.error(request,"User not found")
# return HttpResponse("User not found, not able to login")
pass
else: # Form InValid
# messages.error(request,"Invalid username or password.")
# return HttpResponse("Form Invalid")
context = {
"form" : form
}
return render(request,"loginPage.html",context=context)
# GET
else:
form = AuthenticationForm()
context = {"form":form}
return render(request,"loginPage.html",context=context)
мой код работал нормально, пока я не перешел на модель Custom User и бэкенд Custom Authentication
Как указано в документации отправителем сигнала user_login_failed является:
Имя модуля, используемого для аутентификации.
Это означает, что sender=Usermanagement неверно, причина этого в том, что люди могут иметь различные стратегии аутентификации (т.е. бэкенды), которые могут использовать или не использовать модель пользователя, поэтому пока пользователь не аутентифицирован, Django не может знать, какой класс модели он должен использовать в качестве отправителя. Учитывая, что аутентификация не прошла, Django просто отправляет имя текущего модуля в качестве отправителя
В вашем случае можно просто пропустить аргумент sender и все будет работать нормально:
@receiver(user_login_failed)
def login_failed(sender,credentials,request,**kwargs):
...