Django中的电子邮件验证

时间:2019-04-08 17:05:08

标签: python django authentication web-applications email-verification

我在django中有一个webapp。我尝试使用tokengenerator进行密码重置以创建验证邮件,但未激活电子邮件。

出现问题,

  1. 用户提供电子邮件时,应检查数据库中是否存在电子邮件(数据库将使用用户电子邮件进行更新)
  2. 在验证db中是否存在电子邮件之后,提示用户创建密码 3.创建密码后,用户可以登录到相应页面

有什么解决办法吗?我尝试并遵循

https://medium.com/@frfahim/django-registration-with-confirmation-email-bb5da011e4ef

以上帖子帮助我发送了电子邮件,但用户在验证电子邮件后未激活,尽管我试图检查是否可以进行电子邮件验证,但帖子不符合我的要求。

是否有用于django的任何第三方模块或我提到的要求的任何解决方案。

3 个答案:

答案 0 :(得分:1)

我对您的第一个问题有一个答案:

如果您根据PasswordResetView + PasswordResetConfirmView重置用户密码,则可以执行以下操作:

PasswordResetView负责向用户发送电子邮件。它使用自己的形式输入用户电子邮件-PasswordResetForm。您可以创建自己的表单并从PasswordResetForm继承它。 例如:


class PRForm(PasswordResetForm):
    def clean_email(self):
        email = self.cleaned_data['email']
        if not User.objects.filter(email__iexact=email, is_active=True).exists():
            msg = "There is no user with this email."
            self.add_error('email', msg)
        return email

# User – your user model or any custom model if you have one instead of the default one

此代码将不允许控制器将电子邮件发送到您在数据库中没有的电子邮件地址。

然后在您的VIEW中指定此表单:


class PassResView(RatelimitMixin,  PasswordResetView):
    success_url = 
    from_email = 
    subject_template_name =
    email_template_name =
    success_message = 
    template_name = 
    form_class = PRForm  # here is a custom form
    ratelimit_key = 'ip'
    ratelimit_rate = '10/5m'
    ratelimit_block = True
    ratelimit_method = ('GET', 'POST')

RatelimitMixin不允许某人通过用尽BD来强行使用DB。您可以使用它,也可以不使用-由您自己决定。

答案 1 :(得分:0)

我想出了一个解决方案,但是对于第二个要求,用户必须在创建帐户时输入密码。主要目标是验证用户提供的电子邮件。

模型

class Yourmodel(models.Model):
    first_name = models.CharField(max_length=200)
    second_name = models.CharField(max_length=200)
    email = models.EmailField(max_length=100)

观看次数

def signup(request):
    User = get_user_model()
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data.get('email')
            if Yourmodel.objects.filter(email__iexact=email).count() == 1:
                user = form.save(commit=False)
                user.is_active = False
                user.save()
                current_site = get_current_site(request)
                mail_subject = 'Activate your account.'
                message = render_to_string('email_template.html', {
                            'user': user,
                            'domain': current_site.domain,
                            'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                            'token': account_activation_token.make_token(user),
                        })
                to_email = form.cleaned_data.get('email')
                send_mail(mail_subject, message, 'youremail', [to_email])
                return HttpResponse('Please confirm your email address to complete the registration')
     else:
        form = SignupForm()
    return render(request, 'regform.html', {'form': form})

def activate(request, uidb64, token):
    User = get_user_model()
    try:
        uid = force_text(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
    else:
        return HttpResponse('Activation link is invalid!')

表格

from django.contrib.auth.forms import UserCreationForm


class SignupForm(UserCreationForm):
    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

电子邮件模板

{% autoescape off %}
Hi ,
Please click on the link to confirm your registration,
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
{% endautoescape %}

regform.html

{% csrf_token %}
{% for field in form %}
<label >{{ field.label_tag }}</label>
{{ field }}
{% endfor %}
  

如果您不想与模型中的电子邮件地址进行比较,则可以   跳过,这会将电子邮件发送到提供的电子邮件地址   在注册时没有进一步的确认。

email = form.cleaned_data.get('email')
if Yourmodel.objects.filter(email__iexact=email).count() == 1:

答案 2 :(得分:0)

对于第一个答案,您需要添加 urls.py

path('emailVerification/<uidb64>/<token>', views.activate, name='emailActivate')

而且 emailVerification.html 必须是这样的:

    Hi ,
Please click on the link to confirm your registration,
http://{{ domain }}/emailVerification/{{ uid }}/{{ token }}