Как ограничить пользователя только тремя неправильными otp-записями
Я заставляю своего пользователя вводить otp, который он получает по электронной почте. Но почему-то я не могу сделать цикл, который ограничит его вводить неправильный otp только 3 раза. Если он введет otp неправильно в третий раз, его имя пользователя будет удалено. вот код, который я написал
def registerpage(request):
if request.method == 'POST':
get_otp = request.POST.get('otp')
if get_otp:
get_user= request.POST.get('user')
user = User.objects.get(username=get_user)
if int(get_otp) == UserOtp.objects.filter(user= user).last().otp:
user.is_active = True
user.save()
messages.success(request,'Login to complete the registration process.')
return redirect('login')
else:
messages.error(request, f'OTP entered is wrong')
return render(request, 'register.html', {'otp': True, 'user': user})
first_name = request.POST['first_name']
username = request.POST['email']
password1= request.POST['password']
password2= request.POST['con_password']
email= request.POST['email']
last_name= request.POST['join_as']
if password1==password2:
if User.objects.filter(username=username).exists():
messages.info(request, 'UserID already exists')
return redirect('register')
elif User.objects.filter(email=email).exists():
messages.info(request, 'Email already exists')
return redirect('register')
else:
user=User.objects.create_user(username= username.lower(), password= password1, email= email.lower(), first_name= first_name.upper(), last_name=last_name)
user.is_active = False
user.save()
user_otp = random.randint(100000, 999999)
UserOtp.objects.create(user = user, otp = user_otp)
mess = f"Hello, {user.first_name}, \nYour OTP is {user_otp}\n Thanks!"
send_mail(
"Welcome to Solve Litigation - Verify your Email", #subject
mess, #message
settings.EMAIL_HOST_USER, # sender
[user.email], #reciever
fail_silently= False
)
return render(request, 'register.html', {'otp': True, 'user': user})
else:
messages.info(request, 'Password and Confirm Password not matching')
return redirect('register')
else:
return render(request, 'register.html')
models.py
class UserOtp(models.Model):
user = models.ForeignKey(User, on_delete= models.CASCADE)
time_stamp = models.DateTimeField(auto_now= True)
otp = models.IntegerField()
Я пытался реализовать цикл while и for, но моя логика была неправильной, возможно, и я не получил желаемых результатов, поэтому я убрал циклы на время.
Вы можете хранить количество раз, когда UserOtp
был ошибочным, с помощью целочисленного поля:
class UserOtp(models.Model):
user = models.ForeignKey(User, on_delete= models.CASCADE)
time_stamp = models.DateTimeField(auto_now= True)
otp = models.IntegerField()
wrongs = models.IntegerField(default=0)
В случае если последний UserOtp
для данного пользователя был wrongs=2
и otp снова ошибочен, можно удалить объект user
:
from django.db.models import F
# ⋮
if get_otp:
user = User.objects.get(username=request.POST['user'])
lastotp = UserOtp.objects.filter(user= user).last()
if int(get_otp) == lastotp.otp:
user.is_active = True
user.save()
messages.success(request,'Login to complete the registration process.')
return redirect('login')
elif lastotp.wrongs >= 2:
user.delete()
return redirect('name-of-some-view')
else:
lastotp.wrongs = F('wrongs') + 1
lastotp.save(force_update=True, update_fields=['wrongs'])
messages.error(request, f'OTP entered is wrong')
return render(request, 'register.html', {'otp': True, 'user': user})
Если попытка таким образом не удалась, это увеличит поле wrongs
на единицу. Если в поле wrongs
будет две попытки и совпадение OTP снова будет неверным, мы используем user.delete()
для удаления пользователя.
Однако это представление имеет брешь в безопасности: пользователь может удалить учетные записи других пользователей, просто сделав поддельные POST-запросы с тем же пользователем. Если Алиса, например, хочет удалить Боба, ей достаточно сделать три запроса к представлению с Бобом в качестве поля user
, и тогда учетная запись Боба будет удалена.