Formation incluse

Mise en place de la fonctionnalité mot de passe oublié

Kevin TIAKOUANG DJOU
Kevin TIAKOUANG DJOU
1 Numéro de téléphone 2024 · 19,17 min lecture
0
Django
Mise en place de la fonctionnalité mot de passe oublié

Introduction


Dans l’article précédent, nous avons mis en place la vérification des adresses email à l’aide d’un code OTP (One-Time Password) généré aléatoirement. Cet article nous a permis d’ajouter une couche supplémentaire de sécurité à notre application Django. Aujourd’hui, nous allons implémenter une nouvelle fonctionnalité : la réinitialisation du mot de passe en cas d’oubli. Dans notre approche, nous enverrons un email à l’utilisateur contenant un lien lui permettant de créer un nouveau mot de passe.

1. Création de la fonction d'envoi d'email et du générateur de token de réinitialisation de mot de passe

Dans le fichier tokens.py, ajoutez le code suivant :
 from django.contrib.auth.base_user import AbstractBaseUser

from django.contrib.auth.tokens import PasswordResetTokenGenerator

import six

 

from users.models import User

 

class PasswordResetTokenGeneration(PasswordResetTokenGenerator):

    def _make_hash_value(self, user: User, timestamp: int) -> str:

        returnsix.text_type(user.pk) + six.text_type(timestamp) + six.text_type(user.password))

password_reset_token = PasswordResetTokenGeneration()

 

Dans le fichier emails.py, ajoutez la fonction qui envoie l'email de réinitialisation :

def send_reset_password_link(request, user):

    subject = 'Reset your password'

    domain = get_current_site(request).domain

    uid = urlsafe_base64_encode(force_bytes(user.pk))

    token = password_reset_token.make_token(user)

    link = f'http://{domain}{reverse("users:reset-password", kwargs={"uidb64": uid, "token": token})}' # noqa

    body = f'Click <a href={link}>here</a> to reset your password.'

    send_mail(subject, body, [user.email])

 

 

Importez les éléments nécessaire :

from django.contrib.sites.shortcuts import get_current_site

from django.urls import reverse

from django.utils.encoding import force_bytes

from django.utils.http import urlsafe_base64_encode

from users.tokens import password_reset_token

 

2. Création des formulaires


Dans le fichier forms.py, ajoutez les formulaires suivants :
 class SendResetPasswordEmailForm(Form):

    email = forms.CharField(label='Email',

                            widget=forms.EmailInput(

                                attrs={'class': 'form-control', 'id': 'email', 'placeholder': 'Email'}), required=True, )

 

 

class ResetPasswordForm(Form):

    password = forms.CharField(label='Password',

                               widget=forms.PasswordInput(

                                   attrs={'class': 'form-control', 'id': 'password', 'placeholder': 'Password'}),

                               required=True, )

    confirm_password = forms.CharField(label='Confirm password',

                                       widget=forms.PasswordInput(

                                           attrs={'class': 'form-control', 'id': 'confirm_password',

                                                  'placeholder': 'Confirm password'}),

                                       required=True, )

 

3. Création des vues


Dans le fichier views.py, créez les deux vues nécessaires à la réinitialisation du mot de passe, en ce qui concerne les templates utilisés dans les vues, vous pouvez y avoir accès directement sur le dépôt github :

class SendResetPasswordEmailView(View):

    def get(self, request):

        form = SendResetPasswordEmailForm()

        return render(self.request, template_name='registration/send_reset_password_email.html', context={"form": form})

 

    def post(self, request):

        form = SendResetPasswordEmailForm(self.request.POST)

        if form.is_valid():

            try:

                user = User.objects.get(email=form.cleaned_data['email'])

                with transaction.atomic():

                    try:

              send_reset_password_link(request, user)

              messages.success(request, "We have sent reset password mail", "success")

                    except smtplib.SMTPException:

               messages.error(request, "Error when sending mail please try again later", "danger")

                    except User.DoesNotExist:

               messages.error(request, "User with this email address does not exist", "danger")

        return render(request, template_name='registration/send_reset_password_email.html', context={"form": form})

 

 

def reset_password(request, uidb64, token):

    form = ResetPasswordForm()

    context = {}

    try:

        uid = force_str(urlsafe_base64_decode(uidb64))

        user = User.objects.get(pk=uid)

    except (TypeError, ValueError, OverflowError, User.DoesNotExist):

        user = None

 

    if user is not None and password_reset_token.check_token(user, token):

        if request.method == 'POST':

            form = ResetPasswordForm(request.POST)

            if form.is_valid():

                password = form.cleaned_data['password']

                user.set_password(password)

                user.save()

                messages.success(request, "Your password has been reset.", "success")

                return redirect("login")

    else:

        context['error'] = True

    context['form'] = form

    return render(request, template_name='registration/reset_password.html', context=context)

 

 

Et les importations :
 
from django.utils.encoding import force_str

from django.utils.http import urlsafe_base64_decode

from .tokens import password_reset_token

from .emails import send_reset_password_link

from .forms import SendResetPasswordEmailForm, ResetPasswordForm

 

 

4. Ajout des URLs dans urls.py


Dans le fichier urls.py de l'application users, ajoutez les chemins suivants :

 

path('reset-password/<uidb64>/<token>/', reset_password, name='reset-password'),

path('send-reset-password-link/', SendResetPasswordEmailView.as_view(), name='send-reset-password-link')

 

Conclusion


La fonctionnalité de réinitialisation de mot de passe est cruciale dans le processus d’authentification d’une application web. Dans cet article, nous avons vu comment la mettre en place en envoyant un lien par email à l’utilisateur. Dans le prochain article, nous aborderons la fonctionnalité de changement de mot de passe depuis le compte utilisateur. Vous pouvez consulter le code source de cet article en cliquant ici.

0

Applaudissez pour montrer votre soutien

Kevin TIAKOUANG DJOU

Kevin TIAKOUANG DJOU

2 Suivez-nous · Rédacteur pour Django

Passionné de Django pour sa facilité à créer des applications web robustes, je serais ravi de mettre mes compétences en Python-Django au service to… Lire la suite