Subscribe Us

Header Ads

Forgot Password In Django using Email Link

Forgot Password In Django
Forgot Password Django


follow these steps for forgot password

1. The user enters register email 
2. if the email exists we send a link on that email
3. User will click on the link and enter a new password
4. hit post request by the end of the user using uidb64, token and     new password
5. We validate and verify and send successful change password           message in response
6. that it's, you follow these, I hope you enjoy it.

In Serializers.py


from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.utils.encoding import ( smart_str, force_str, smart_bytes,
DjangoUnicodeDecodeError ) from django.utils.http import (urlsafe_base64_decode,
urlsafe_base64_encode ) from rest_framework import exceptions

# Forgot Password


class ResetPasswordRequestSerializer(serializers.Serializer):

    email = serializers.EmailField(min_length=2)

    class Meta:

        fields = ['email']


class SetNewPasswordSerializer(serializers.Serializer):

    password = serializers.CharField(
        min_length=6, max_length=68, write_only=True)
    token = serializers.CharField(min_length=1, write_only=True)
    uidb64 = serializers.CharField(min_length=1, write_only=True)

    class Meta:

        fields = ['password', 'token', 'uidb64']

    def validate(self, attrs):

        try:
            password = attrs.get('password')
            token = attrs.get('token')
            uidb64 = attrs.get('uidb64')

            id = force_str(urlsafe_base64_decode(uidb64))

            user = User.objects.get(id=id)
            if not PasswordResetTokenGenerator().check_token(user, token):
                raise exceptions.AuthenticationFailed(
                    'The reset link is invalid', 401)
            user.set_password(password)
            user.save()
            return user
        except Exception as e:
            raise exceptions.AuthenticationFailed(
                'The reset link is invalid', 401)

        return super().validate(attrs)


Views.py

# Reset Password

from django.contrib.auth.tokens import                                        PasswordResetTokenGenerator
from django.utils.encoding import smart_str, force_str,                      smart_bytes, DjangoUnicodeDecodeError
from django.utils.http import urlsafe_base64_decode,                          urlsafe_base64_encode
from django.contrib.sites.shortcuts import get_current_site
from django.urls import reverse
from modules.core.utils import Util

# Forgot Password

class RequestPasswordResetEmailView(generics.GenericAPIView):
    serializer_class = serializers.ResetPasswordRequestSerializer

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        email = request.data['email']

        if User.objects.filter(email=email).exists():
            user = User.objects.get(email=email)
            uidb64 = urlsafe_base64_encode(smart_bytes(user.id))
            token =                                                               PasswordResetTokenGenerator().make_token(user)
            current_site = get_current_site(
                request=request).domain

            relative_link = reverse(
                'password-reset-confirm', kwargs=                                 {'uidb64':uidb64, 'token': token})

            absurl = 'http://' + current_site + relative_link
            email_body = 'Hello \n Use link below to reset your                           password \n' + absurl

            data = {'email_body': email_body, 
                    'to_email':user.email,
                    'email_subject': 'Reset your password'}

            Util.send_email(data)

        return Response({'success': 'We have sent you a link to                          reset your password on email'})


class PasswordTokenCheckAPI(generics.GenericAPIView):
    def get(self, request, uidb64, token):
        try:
            id = smart_str(urlsafe_base64_decode(uidb64))
            user = User.objects.get(id=id)

            if not PasswordResetTokenGenerator().check_token(
                user,token):
                return Response({'error': 'Token is not valid,                                     Please Request a new One'})

            return Response({'success': True, 'message':                                       'Credentials Valid',
                             'uidb64': uidb64, 
                             'token': token})

        except DjangoUnicodeDecodeError as e:
            if not PasswordResetTokenGenerator():
                return Response({'error': 'Token is not valid,                                      Please Request a new One'})


class SetNewPasswordView(generics.GenericAPIView):
    serializer_class = serializers.SetNewPasswordSerializer

    def patch(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response({
            'sucess': True,
            'message': 'Password Reset Success'
        })


Urls.py

  
path('request-reset-email/',                                                 views.RequestPasswordResetEmailView.as_view(),                    name='request-reset-email'), 
   
path('password-reset/<uidb64>/<token>/',                                      views.PasswordTokenCheckAPI.as_view(), 
            name='password-reset-confirm'),
    
path('password-reset-complete/',                                              views.SetNewPasswordView.as_view(),                               name='password-reset-complete'), 
        
path('password-reset/<uidb64>/<token>/',                                      views.PasswordTokenCheckAPI.as_view(), 
            name='password-reset-confirm'),    

path('password-reset-complete/',                                              views.SetNewPasswordView.as_view(),
            name='password-reset-complete'),


Send Email

from django.core.mail import EmailMessage


class Util:
    @staticmethod
    def send_email(data):
        email = EmailMessage(
                 subject=data['email_subject'],                                      body=data['email_body'], 
                  from_email='tech@tecgslate.com',
                  to=[data['to_email']]
        )
        email.send()

Post a Comment

0 Comments