MyGear - User-Registrierung mit eMail-Bestätigung

- Veröffentlicht unter Programmieren von - Permalink

User können sich aktuell einfach so registrieren. Um Fake-Accounts zu verhindern, soll eine Registrierung nur möglich sein, nachdem der User in einer Mail auf einen Bestätigungslink geklickt hat.

In der ursprünglichen signup.html ändert sich nichts. In der urls.py ergänze ich:

path(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', activate, name='activate'),

In der views.py kommt die Funktion dazu und die signup wird ergänzt:

from django.shortcuts import render, redirect
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.utils.http import urlsafe_base64_encode,urlsafe_base64_decode
from django.utils.encoding import force_bytes,force_str
from django.core.mail import EmailMessage
from .models import MyUser
from .forms import RegisterForm
from .tokens import activation_token

def signup(request):
    if request.method=="POST":
        form=RegisterForm(request.POST)
        if form.is_valid():
            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('signup_email.html',{'user':user,'domain':current_site.domain,'uid':urlsafe_base64_encode(force_bytes(user.pk)),'token':activation_token.make_token(user),})
            to_email=form.cleaned_data.get('email')
            email=EmailMessage(mail_subject,message,to=[to_email])
            email.send()
            return render(request, 'signup_email_send.html')
        else:
            return render(request, 'signup.html', {'form':form})
    else:
        form=RegisterForm()
        return render(request, 'signup.html', {'form':form})

def activate(request,uidb64,token):
    try:
        uid=force_str(urlsafe_base64_decode(uidb64))
        user=MyUser.objects.get(pk=uid)
    except(TypeError,ValueError,OverflowError,User.DoesNotExist):
        user=None
    if user is not None and activation_token.check_token(user,token):
        user.is_active=True
        user.save()
        login(request,user)
        return render(request, 'home.html', {'user':request.user})
    else:
        return render(request, 'signup_email_wrong_token.html')

Dann lege ich eine token.py an.

from django.contrib.auth.tokens import PasswordResetTokenGenerator
import six

class TokenGenerator(PasswordResetTokenGenerator):
    def _make_hash(self, user, timestamp):
        return (six.text_type(user.pk)+six.text_type(timestamp)+six.text_type(user.is_active))

activation_token=TokenGenerator()

Und dann noch die Templatses dazu:

signup_email_send.html

{% extends "home.html" %}

{% block login %}
    <h2>Activation Email Sent</h2>
    <p>We've sent you instructions for setting up your account to the email address you submitted.</p>
    <p>You should receive the email shortly. If you don't see it, please check your spam folder.</p>
    <p>If you don't receive an email, make sure you've entered the right email address.</p>
    <a href="{% url 'home' %}">Back to Home</a>
{% endblock %}
signup_email_wrong_token.html

{% extends "home.html" %}

{% block login %}
    <h2>Activation Link is invalid</h2>
    <p>Please try again.</p>
    <a href="{% url 'home' %}">Back to Home</a>
{% endblock %}
Schlagworte: