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
A simple app that provides django integration for RQ (Redis Queue)

Django-RQ Django integration with RQ, a Redis based Python queuing library. Django-RQ is a simple app that allows you to configure your queues in djan

RQ 1.6k Jan 06, 2023
Fully reponsive Chat Application built with django, javascript, materialUi, bootstrap4, html and css.

Chat app (Full Stack Frameworks with Django Project) Fully reponsive Chat Application built with django, javascript, materialUi, bootstrap4, html and

1 Jan 19, 2022
A CBV to handle multiple forms in one view

django-shapeshifter A common problem in Django is how to have a view, especially a class-based view that can display and process multiple forms at onc

Kenneth Love 167 Nov 26, 2022
A Django app that creates automatic web UIs for Python scripts.

Wooey is a simple web interface to run command line Python scripts. Think of it as an easy way to get your scripts up on the web for routine data anal

Wooey 1.9k Jan 08, 2023
simple project management tool for educational purposes

Taskcamp This software is used for educational and demonstrative purposes. It's a simple project management tool powered by Django Framework Install B

Ilia Dmitriev 6 Nov 08, 2022
Docker django app

Hmmmmm... What I should write here? Maybe "Hello World". Hello World Build Docker compose: sudo docker-compose build Run Docker compose: sudo docker-

Andrew 0 Nov 10, 2022
It's the assignment 1 from the Python 2 course, that requires a ToDoApp with authentication using Django

It's the assignment 1 from the Python 2 course, that requires a ToDoApp with authentication using Django

0 Jan 20, 2022
Login System Django

Login-System-Django Login System Using Django Tech Used Django Python Html Run Locally Clone project git clone https://link-to-project Get project for

Nandini Chhajed 6 Dec 12, 2021
A slick ORM cache with automatic granular event-driven invalidation.

Cacheops A slick app that supports automatic or manual queryset caching and automatic granular event-driven invalidation. It uses redis as backend for

Alexander Schepanovski 1.7k Jan 03, 2023
Django application and library for importing and exporting data with admin integration.

django-import-export django-import-export is a Django application and library for importing and exporting data with included admin integration. Featur

2.6k Dec 26, 2022
A reusable Django app that configures your project for deployment

django-simple-deploy This app gives you a management command that configures your project for an initial deployment. It targets Heroku at the moment,

Eric Matthes 205 Dec 26, 2022
Django React - Purity Dashboard (Open-Source) | AppSeed

Django React Purity Dashboard Start your Development with an Innovative Admin Template for Chakra UI and React. Purity UI Dashboard is built with over

App Generator 19 Sep 19, 2022
Management commands to help backup and restore your project database and media files

Django Database Backup This Django application provides management commands to help backup and restore your project database and media files with vari

687 Jan 04, 2023
Projeto onde podes inserir notícias, ver todas as notícias guardas e filtrar por tag. A base de dados usada é o mongoDB.

djangoProject Projeto onde podes inserir notícias, ver todas as notícias guardas e filtrar por tag. A base de dados usada é o mongoDB. packages utiliz

Sofia Rocha 1 Feb 22, 2022
Probably the best abstract model / admin for your tree based stuff.

django-treenode Probably the best abstract model / admin for your tree based stuff. Features Fast - get ancestors, children, descendants, parent, root

Fabio Caccamo 360 Jan 05, 2023
Per object permissions for Django

django-guardian django-guardian is an implementation of per object permissions [1] on top of Django's authorization backend Documentation Online docum

3.3k Jan 04, 2023
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
Neighbourhood - A python-django web app to help the residence of a given neighborhood know their surrounding better

Neighbourhood A python-django web app to help the residence of a given neighborh

Levy Omolo 4 Aug 25, 2022
An airlines clone website with django

abc_airlines is a clone website of an airlines system the way it works is that first you add flights to the website then the users can search flights

milad 1 Nov 16, 2021
Boilerplate Django Blog for production deployments!

CFE Django Blog THIS IS COMING SOON This is boilerplate code that you can use to learn how to bring Django into production. TLDR; This is definitely c

Coding For Entrepreneurs 26 Dec 09, 2022