Forgot password functionality build in Python / Django Rest Framework

Related tags

Djangoforgot-password
Overview

Password Recover

Recover password functionality with e-mail sender usign Django Email Backend

How to start project.

  • Create a folder in your machine
  • Create a virtual environment
    • python3 -m venv venv
  • Start the virtual environment
    • . venv/bin/activate (Linux)
    • venv/Scripts/Activate (Windows)
  • Inside your venv folder clone the project
    • git clone https://github.com/alexlopesbr/forgot-password.git
  • In your-new-folder/venv/forgot-password
    • pip install -r requirements.txt to install the project's dependencies
    • python manage.py migrate to generate your database
    • python3 manage.py createsuperuser to create the admin
    • python3 manage.py runserver to start the server
  • Open your browser and go to http://127.0.0.1:8000/admin/
  • Login with the admin credentials
    • Now you can see you user and some info in admin panel

Using the functionality

We have two POST requests:

{{localhost}}/core/user/forgot-password/ Send an e-mail with a link to recover the password.

body of the request:

    {
        "email": "email from you user created"
    }

{{localhost}}/core/user/change-forgotten-password/ Allows you to enter the new password.

body of the request:

    {
        "email": "email from you user created",
        "forgot_password_hash": "inside the redefine you passwod button sended to your email",
        "new_password": "set a new password"
    }

You can use Postman or Insomnia to test the requests.
Note: When you start your server the localhost generaly is http://127.0.0.1:8000/.


Some instructions and informations

root

setings.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

BASE_URL = 'sandbox.com'

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'your-key'
EMAIL_PORT = 587
EMAIL_USE_TLS = True

First step, set some configures in settings.py. Don't forget to set the EMAIL_HOST_USER and the EMAIL_HOST_PASSWORD.


core

views.py

from core.models import User
from rest_framework.response import Response
from .services import send_forgot_password_email
from .exceptions import ForgotPasswordInvalidParams
from rest_framework.permissions import AllowAny
from rest_framework.decorators import action

@action(detail=False, methods=['post'], url_path='forgot-password', permission_classes=[AllowAny])
def forgot_password(self, request):
    if 'email' not in request.POST:
        raise ForgotPasswordInvalidParams
    send_forgot_password_email(request.POST['email'])
    return Response({'worked': True})

@action(detail=False, methods=['post'], url_path='change-forgotten-password', permission_classes=[AllowAny])
def change_forgotten_password(self, request):
    email = request.POST.get('email', None)
    forgot_password_hash = request.POST['forgot_password_hash']
    new_password = request.POST['new_password']
    User.change_password(email, forgot_password_hash, new_password)
    return Response({'worked': True})

Here we create a request called forgot-password to send an email with a link to change the password.
In this case, we are calling the send_forgot_password_email function. (see the function details below)

We also create a change-forgotten-password request to change the password. Here we need to send the email, the hash and the new password.

Obs. the hash is an inplicit parameter that is generated by the send_forgot_password_email function.

forgot_password_hash and new_password fields are set in core.models.py

services.py

from core.models import User
from emails.services import send_email_forgot_password
from core.exceptions import UserDoesNotExist
from django.utils import timezone
from datetime import timedelta
import re
import urllib.parse

def send_forgot_password_email(email):
    try:
        user = User.objects.get(email=email)
    except User.DoesNotExist:
        raise UserDoesNotExist
    now = timezone.now()
    user.forgot_password_hash = re.sub(r'\D', '', str(now))
    user.forgot_password_expire = now + timedelta(hours=24)
    user.save()
    link = 'https://forgot-password.com/change-password?email=%s&hash=%s' % (
        urllib.parse.quote(user.email), user.forgot_password_hash)
    send_email_forgot_password(user.email, link)

In this function we gererate a hash with a simple timezone.now() that will be atribuate to forgot_password_hash. This will be our validator.
We also set the forgot_password_expire field with the same timezone.now() plus the timedelta of 24 hours. So we give to user 24 hours to change the password.
We can bring another informations like the name of the user, but we don't use it in this exemple.

In the send_email_forgot_password function we send the email with the link to change the password.


emails

services.py

from django.core.mail import EmailMessage
from django.conf import settings


def open_and_return(my_file):
    with open(settings.BASE_DIR + '/emails/templates/' + my_file, 'r', encoding="utf-8") as file:
        data = file.read()
    return data


def send_email_forgot_password(email, link):
    template = open_and_return("forgot-password.html").format(link)

    msg = EmailMessage(
        u'Email forgot password received',
        template,
        to=[email, ],
        from_email=settings.EMAIL_HOST_USER
    )

    msg.content_subtype = 'html'
    msg.send()

The last step is sending the email with the link to user to change the password.

open_and_return function opens the template and returns the content.
This template is in emails/templates/forgot-password.html and will be used to lets our email message prettier.
In template = open_and_return("forgot-password.html").format(link) we replace the link with the link that was setted in the send_forgot_password_email function.

More information about sending emails in Django documentation

Owner
alexandre Lopes
Graduated in Biological Sciences and now back end developer, I build API's in Python / Django Rest Framework but I confess that I love front end too.
alexandre Lopes
Tools to easily create permissioned CRUD endpoints in graphene-django.

graphene-django-plus Tools to easily create permissioned CRUD endpoints in graphene-django. Install pip install graphene-django-plus To make use of ev

Zerosoft 74 Aug 09, 2022
An automatic django's update checker and MS teams notifier

Django Update Checker This is small script for checking any new updates/bugfixes/security fixes released in django News & Events and sending correspon

prinzpiuz 4 Sep 26, 2022
Django admin CKEditor integration.

Django CKEditor NOTICE: django-ckeditor 5 has backward incompatible code moves against 4.5.1. File upload support has been moved to ckeditor_uploader.

2.2k Dec 31, 2022
A GitHub Action for checking Django migrations

🔍 Django migrations checker A GitHub Action for checking Django migrations About This repository contains a Github Action that checks Django migratio

Oda 5 Nov 15, 2022
Simple yet powerful and really extendable application for managing a blog within your Django Web site.

Django Blog Zinnia Simple yet powerful and really extendable application for managing a blog within your Django Web site. Zinnia has been made for pub

Julien Fache 2.1k Dec 24, 2022
Simpliest django(uvicorn)+postgresql+nginx docker-compose (ready for production and dev)

simpliest django(uvicorn)+postgresql+nginx docker-compose (ready for production and dev) To run in production: docker-compose up -d Site available on

Artyom Lisovskii 1 Dec 16, 2021
Strict separation of config from code.

Python Decouple: Strict separation of settings from code Decouple helps you to organize your settings so that you can change parameters without having

Henrique Bastos 2.3k Jan 04, 2023
A set of high-level abstractions for Django forms

django-formtools Django's "formtools" is a set of high-level abstractions for Django forms. Currently for form previews and multi-step forms. This cod

Jazzband 621 Dec 30, 2022
Compresses linked and inline javascript or CSS into a single cached file.

Django Compressor Django Compressor processes, combines and minifies linked and inline Javascript or CSS in a Django template into cacheable static fi

2.6k Jan 03, 2023
Django model mixins and utilities.

django-model-utils Django model mixins and utilities. django-model-utils supports Django 2.2+. This app is available on PyPI. Getting Help Documentati

Jazzband 2.4k Jan 04, 2023
Cached file system for online resources in Python

Minato Cache & file system for online resources in Python Features Minato enables you to: Download & cache online recsources minato supports the follo

Yasuhiro Yamaguchi 10 Jan 04, 2023
Full control of form rendering in the templates.

django-floppyforms Full control of form rendering in the templates. Authors: Gregor Müllegger and many many contributors Original creator: Bruno Renié

Jazzband 811 Dec 01, 2022
Django React Flight Rezervation

Django Intro & Installation python -m venv venv source ./venv/Scripts/activate pip install Django pip install djangorestframework pip install python-d

HILMI SARIOGLU 2 May 26, 2022
Redia Cache implementation in django.

django-redis Recipe APP Simple Recipe app which shows different kinds off recipe to the user. Why Cache ? Accessing data from cache is much faster tha

Avinash Alanjkar 1 Sep 21, 2022
Django Simple Spam Blocker is blocking spam by regular expression.

Django Simple Spam Blocker is blocking spam by regular expression.

Masahiko Okada 23 Nov 29, 2022
Forgot password functionality build in Python / Django Rest Framework

Password Recover Recover password functionality with e-mail sender usign Django Email Backend How to start project. Create a folder in your machine Cr

alexandre Lopes 1 Nov 03, 2021
Blog focused on skills enhancement and knowledge sharing. Tech Stack's: Vue.js, Django and Django-Ninja

Blog focused on skills enhancement and knowledge sharing. Tech Stack's: Vue.js, Django and Django-Ninja

Wanderson Fontes 2 Sep 21, 2022
Store events and publish to Kafka

Create an event from Django ORM object model, store the event into the database and also publish it into Kafka cluster.

Diag 6 Nov 30, 2022
Django API creation with signed requests utilizing forms for validation.

django-formapi Create JSON API:s with HMAC authentication and Django form-validation. Version compatibility See Travis-CI page for actual test results

5 Monkeys 34 Apr 04, 2022
Pipeline is an asset packaging library for Django.

Pipeline Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript templ

Jazzband 1.4k Jan 03, 2023