Есть ли возможность поставить условие на требуемый пароль в Django Custom Auth?
Я хочу, чтобы зарегистрированный пользователь сначала входил в систему с помощью Email или номера телефона и пароля. Если пользователь забыл пароль, то должна быть возможность войти в систему с помощью OTP, минуя пароль, который будет предоставлен через SMS на номер телефона пользователя. Есть ли возможность достичь этого?
Вот официальные документы, в которых поле пароля всегда является обязательным. https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#a-full-example. Я знаю, что мы можем изменить имя пользователя на email или на номер телефона, если захотим, но как нам поставить условие для входа с паролем/случайным OTP. Как мы можем этого добиться? За предложение буду благодарен. Спасибо
Да, мы можем сделать это, используя принудительный вход, вот пример того, как я это сделал, пожалуйста, посмотрите. У меня есть профиль, который один к одному связан с пользователем
def login_otp(request):
mobile = request.session['mobile']
context = {'mobile':mobile}
if request.method == 'POST':
otp = request.POST.get('otp')
profile = Profile.objects.filter(mobile=mobile).first()
if otp == profile.otp:
user = User.objects.get(id = profile.user.id)
login(request , user)
return redirect('cart')
else:
context = {'message' : 'Wrong OTP' , 'class' : 'danger','mobile':mobile }
return render(request,'login_otp.html' , context)
return render(request,'login_otp.html' , context)
Вы можете сделать свой собственный CustomLoginBackend как
from django.contrib.auth import get_user_model
class CustomLoginBackend(object):
def authenticate(self, request, email, password, otp):
User = get_user_model()
try:
user = User.objects.using(db_name).get(email=email)
except User.DoesNotExist:
return None
else:
if password is not None:
if getattr(user, 'is_active', False) and user.check_password(password):
return user
else:
if getattr(user, 'is_active', False) and user.otp == otp: #<-- otp included in user table
return user
return None
Тогда в ваших login представлениях.
from django.contrib.auth import authenticate, login
from django.contrib import messages
def login_view(request):
if request.method == 'POST':
email = request.POST.get('email', None)
password = request.POST.get('password', None)
otp = request.POST.get('otp', None)
user = authenticate(request, email=email, password=password, otp=otp)
if user is not None:
login(request, user)
# redirect to a success page
return redirect('dashboard')
else:
if password is not None:
# return either email or password incorrect
messages.error(request, "Invalid Email or Password")
return redirect('login')
else:
# return invalid otp
messages.error(request, "Invalid OTP")
return redirect('login')
return render(request, 'login.html')
И, наконец, не забудьте добавить AUTHENTICATION_BACKENDS в свой settings.py в качестве
AUTHENTICATION_BACKENDS = ['path_to_your.CustomLoginBackend ',]