Я работал над созданием системы сброса пароля на своем сайте django
Я намерен также использовать аналогичную систему для подтверждения создания учетной записи, но в данный момент я не могу протестировать систему, так как у меня возникли проблемы с моей учетной записью mailgun
определить пароль_reset_request(запрос): если request.method == 'POST': электронная почта = request.POST.get('электронная почта') попробуйте: user = get_user_model().objects.get(email=электронная почта)
# Generate reset token and expiry
profile, created = UserProfile.objects.get_or_create(user=user)
profile.generate_reset_token()
# Prepare the email context with the reset token
context = {
'user': user,
'reset_token': profile.reset_token, # Send the reset token in the email
}
# Render email templates
email_html = render_to_string('password_reset_email.html', context)
email_plain = strip_tags(email_html)
# Mailgun API setup
mailgun_url = f"https://api.mailgun.net/v4/{MAILGUN_DOMAIN_NAME}/messages"
mailgun_auth = ("api", MAILGUN_API_KEY)
mailgun_data = {
"from":DEFAULT_FROM_EMAIL,
"to": user.email,
"subject": "Password Reset Request",
"text": email_plain,
"html": email_html
}
# Send email via Mailgun API
try:
response = requests.post(mailgun_url, auth=mailgun_auth, data=mailgun_data, verify=False)
if response.status_code == 200:
messages.success(request, "A password reset token has been sent to your email.")
else:
messages.warning(request, "Password reset requested, but there was an issue sending the email.")
except requests.exceptions.RequestException as e:
messages.warning(request, f"Password reset requested, but we couldn't send the email: {str(e)}")
return redirect('password_reset_verify')
except get_user_model().DoesNotExist:
messages.error(request, "Email address not found.")
return render(request, 'password_reset_request.html')
определите пароль для повторной проверки(запрос): если request.method == 'POST': токен = request.POST.get('токен') # Предполагается, что пользователь вводит токен здесь , если токен: пробовать: # Найдите профиль пользователя, используя токен profile = UserProfile.objects.get(reset_token=токен)
if profile.is_reset_token_valid():
# Create the uidb64 from user ID (convert user ID to string before encoding)
uidb64 = urlsafe_base64_encode(str(profile.user.pk).encode())
# Use the reset token
token = profile.reset_token
# Redirect to the password reset confirmation page with parameters
return redirect('password_reset_confirm', uidb64=uidb64, token=token)
else:
messages.error(request, "The reset token is invalid or has expired.")
except UserProfile.DoesNotExist:
messages.error(request, "Invalid token.")
else:
messages.error(request, "No token provided.")
return render(request, 'password_reset_verify.html')
из файла .forms импортируем форму ввода пароля
определение пароля_reset_confirm(запрос, uidb64, токен): пробовать: # Расшифруем uidb64 и получим uid пользователя = urlsafe_base64_decode(uidb64).расшифруем('utf-8') user = get_user_model().objects.get(pk=uid)
# Check if the token is valid for this user
profile = UserProfile.objects.get(user=user)
if not profile.is_reset_token_valid() or profile.reset_token != token:
messages.error(request, "The reset token is invalid or has expired.")
return redirect('password_reset_request') # Redirect to the reset request page
# If the token is valid, proceed with the password reset
if request.method == 'POST':
form = PasswordResetForm(user=user, data=request.POST)
if form.is_valid():
form.save()
messages.success(request, "Your password has been reset successfully.")
return redirect('login') # Redirect to the login page after successful password reset
else:
form = PasswordResetForm(user=user)
except (TypeError, ValueError, OverflowError, UserProfile.DoesNotExist):
messages.error(request, "Invalid token or user.")
return redirect('password_reset_request')
return render(request, 'password_reset_confirm.html', {'form': form})
из django.contrib.auth.forms импортируем SetPasswordForm
класс PasswordResetForm(SetPasswordForm): """Пользовательская форма сброса пароля для обработки логики сброса пароля."""
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get("new_password1")
confirm_password = cleaned_data.get("new_password2")
if password != confirm_password:
raise forms.ValidationError("The two password fields must match.")
return cleaned_data
импортировать случайную строку импорта из django.utils импортировать часовой пояс
Пользователь = get_user_model()
класс UserProfile(models.Model): пользователь = models.OneToOneField(Пользователь, on_delete=models.КАСКАД, имя_связи="профиль")
# Reset token fields
reset_token = models.CharField(max_length=6, null=True, blank=True)
reset_token_expiry = models.DateTimeField(null=True, blank=True)
SPECIALTY_CHOICES = [
('Beauticians', 'Beauticians'),
('Hairdressers', 'Hairdressers'),
('Nail Technicians', 'Nail Technicians'),
('Tattoo Artists', 'Tattoo Artists'),
('Dog Groomers', 'Dog Groomers'),
('Aesthetic Practitioners', 'Aesthetic Practitioners'),
('Sports Therapists', 'Sports Therapists'),
('Physiotherapists', 'Physiotherapists'),
('Chiropractors', 'Chiropractors'),
('Semi-Permanent Makeup Artists', 'Semi-Permanent Makeup Artists'),
]
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
specialty = models.CharField(max_length=100, choices=SPECIALTY_CHOICES, blank=True, null=True)
def __str__(self):
return f"Profile for {self.user.username} ({self.get_specialty_display()})"
def generate_reset_token(self):
"""Generate a random 6-digit numeric token and ensure uniqueness."""
self.reset_token = ''.join(random.choices(string.digits, k=6)) # Using only digits for simplicity
self.reset_token_expiry = timezone.now() + timedelta(hours=1) # Token expires in 1 hour
self.save()
def is_reset_token_valid(self):
"""Check if the reset token is still valid."""
return self.reset_token and self.reset_token_expiry and timezone.now() < self.reset_token_expiry
def clear_reset_token(self):
"""Clears the reset token after use."""
self.reset_token = None
self.reset_token_expiry = None
self.save()