reset_password中的链接无效



我想在Django中编写一个自定义用户,但重置密码有问题。我使用下面的URL作为URLs.py

url(r'^reset_password_confirm/(?P<uidb64>[0-9A-Za-z_-']+)-(?P<token>[0-9A-Za-z-']+)/$', PasswordResetConfirmView.as_view() , name='reset_password_confirm'),
url(r'^reset_password', ResetPasswordRequestView.as_view())

这是我对重置密码和确认的看法

class ResetPasswordRequestView(FormView):
# User = get_user_model()
template_name = "test_template.html"    #code for template is given below the view's code
success_url = 'reset_password'
form_class = PasswordResetRequestForm
@staticmethod
def validate_email_address(email):
try:
validate_email(email)
return True
except ValidationError:
return False
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
data= form.cleaned_data["email_or_username"]
if self.validate_email_address(data) is True:                 #uses the method written above
'''
If the input is an valid email address, then the following code will lookup for users associated with that email address. If found then an email will be sent to the address, else an error message will be printed on the screen.
'''
associated_users= User.objects.filter(Q(email=data)|Q(username=data))
if associated_users.exists():
for user in associated_users:
c = {
'email': user.email,
'domain': request.META['HTTP_HOST'],
'site_name': 'your site',
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'user': user,
'token': default_token_generator.make_token(user),
'protocol': 'http',
}
subject_template_name='password_reset_subject.txt' 
# copied from django/contrib/admin/templates/registration/password_reset_subject.txt to templates directory
email_template_name='password_reset_email.html'    
# copied from django/contrib/admin/templates/registration/password_reset_email.html to templates directory
subject = loader.render_to_string(subject_template_name, c)
# Email subject *must not* contain newlines
subject = ''.join(subject.splitlines())
email = loader.render_to_string(email_template_name, c)
send_mail(subject, email, DEFAULT_FROM_EMAIL , [user.email], fail_silently=False)
result = self.form_valid(form)
messages.success(request, 'An email has been sent to ' + data +". Please check its inbox to continue reseting password.")
return result
result = self.form_invalid(form)
messages.error(request, 'No user is associated with this email address')
return result
else:
'''
If the input is an username, then the following code will lookup for users associated with that user. If found then an email will be sent to the user's address, else an error message will be printed on the screen.
'''
associated_users= User.objects.filter(username=data)
if associated_users.exists():
for user in associated_users:
c = {
'email': user.email,
'domain': 'example.com', #or your domain
'site_name': 'example',
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'user': user,
'token': default_token_generator.make_token(user),
'protocol': 'http',
}
subject_template_name='password_reset_subject.txt'
email_template_name='password_reset_email.html'
subject = loader.render_to_string(subject_template_name, c)
# Email subject *must not* contain newlines
subject = ''.join(subject.splitlines())
email = loader.render_to_string(email_template_name, c)
send_mail(subject, email, DEFAULT_FROM_EMAIL , [user.email], fail_silently=False)
result = self.form_valid(form)
messages.success(request, 'Email has been sent to ' + data +"'s email address. Please check its inbox to continue reseting password.")
return result
result = self.form_invalid(form)
messages.error(request, 'This username does not exist in the system.')
return result
messages.error(request, 'Invalid Input')
return self.form_invalid(form)  
class PasswordResetConfirmView(FormView):
template_name = "password_reset_confirm.html"
success_url = 'admin'
form_class = SetPasswordForm
def post(self, request, uidb64=None, token=None, *arg, **kwargs):
"""
View that checks the hash in a password reset link and presents a
form for entering a new password.
"""
UserModel = get_user_model()
form = self.form_class(request.POST)
assert uidb64 is not None and token is not None  # checked by URLconf
try:
uid = urlsafe_base64_decode(uidb64)
user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
user = None
if user is not None and default_token_generator.check_token(user, token):
if form.is_valid():
new_password= form.cleaned_data['new_password2']
user.set_password(new_password)
user.save()
messages.success(request, 'Password has been reset.')
return self.form_valid(form)
else:
messages.error(request, 'Password reset has not been unsuccessful.')
return self.form_invalid(form)
else:
messages.error(request,'The reset password link is no longer valid.')
return self.form_invalid(form) 

它发送一封包含无效链接的电子邮件,如HTTP://127.0.0.1:8000/reset_password_confirm/b'MjM'-4y1-68809e63d52242805bd7/

当我点击它时,我收到了这条消息,显示它是无效的CCD_ 2。

我搜索了很多,没有找到任何解决方案。有人能帮我吗?非常感谢

如果您使用的是CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True,您的url必须在https中。

您有两个选项。重写reset.html模板,在rootprojecttemplatesregistrationpassword_reset_email.html中创建一个文件

内容可以强制https,模板是:

{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you 
requested a password reset for your user account at
{{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a 
new password:" %}
{% block reset_link %}
https://{{ domain }}{% url 'password_reset_confirm' 
uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} 
{{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}

选项2:您必须确保您的服务器运行在https上,模板电子邮件搜索请求.schema if是http或https,并且填充了使用的架构。我的nginx服务器通过https作为代理,但我的django服务器通过http运行,因此我的电子邮件模板只使用http。

最新更新