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
RestApi With Django 3.2 And Django Rest Framework

RestApi-With-Django-3.2-And-Django-Rest-Framework Description This repository is a Software of Development with Python. Virtual Using pipenv, virtuale

Daniel Arturo Alejo Alvarez 6 Aug 02, 2022
Mobile Detect is a lightweight Python package for detecting mobile devices (including tablets).

Django Mobile Detector Mobile Detect is a lightweight Python package for detecting mobile devices (including tablets). It uses the User-Agent string c

Botir 6 Aug 31, 2022
Super simple bar charts for django admin list views visualizing the number of objects based on date_hierarchy using Chart.js.

Super simple bar charts for django admin list views visualizing the number of objects based on date_hierarchy using Chart.js.

foorilla LLC 4 May 18, 2022
This is a Django app that uses numerous Google APIs such as reCAPTURE, maps and waypoints

Django project that uses Googles APIs to auto populate fields, display maps and routes for multiple waypoints

Bobby Stearman 57 Dec 03, 2022
A UUIDField for Django

django-uuidfield Provides a UUIDField for your Django models. Installation Install it with pip (or easy_install): pip install django-uuidfield Usage

David Cramer 265 Nov 30, 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
Django based webapp pulling in crypto news and price data via api

Deploy Django in Production FTA project implementing containerization of Django Web Framework into Docker to be placed into Azure Container Services a

0 Sep 21, 2022
I managed to attach the Django Framework to my Telegram Bot and set a webhook

I managed to attach the Django Framework to my Telegram Bot and set a webhook. I've been developing it from 10th of November 2021 and I want to have a basic working prototype.

Valentyn Vovchak 2 Sep 08, 2022
Official clone of the Subversion repository.

Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. All documentation is in the "docs" directo

Raymond Penners 3 May 06, 2022
Django + AWS Elastic Transcoder

Django Elastic Transcoder django-elastic-transcoder is an Django app, let you integrate AWS Elastic Transcoder in Django easily. What is provided in t

StreetVoice 66 Dec 14, 2022
django-dashing is a customisable, modular dashboard application framework for Django to visualize interesting data about your project. Inspired in the dashboard framework Dashing

django-dashing django-dashing is a customisable, modular dashboard application framework for Django to visualize interesting data about your project.

talPor Solutions 703 Dec 22, 2022
Source code for Django for Beginners 3.2

The official source code for https://djangoforbeginners.com/. Available as an ebook or in Paperback. If you have the 3.1 version, please refer to this

William Vincent 10 Jan 03, 2023
Store model history and view/revert changes from admin site.

django-simple-history django-simple-history stores Django model state on every create/update/delete. This app supports the following combinations of D

Jazzband 1.8k Jan 06, 2023
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
Use minify-html, the extremely fast HTML + JS + CSS minifier, with Django.

django-minify-html Use minify-html, the extremely fast HTML + JS + CSS minifier, with Django. Requirements Python 3.8 to 3.10 supported. Django 2.2 to

Adam Johnson 60 Dec 28, 2022
A generic system for filtering Django QuerySets based on user selections

Django Filter Django-filter is a reusable Django application allowing users to declaratively add dynamic QuerySet filtering from URL parameters. Full

Carlton Gibson 3.9k Jan 03, 2023
A prettier way to see Django requests while developing

A prettier way to see Django requests while developing

Adam Hill 35 Dec 02, 2022
Repo for All the Assignments I have to submit for Internship Application !😅

Challenges Repository for All the Assignments I have to submit for Internship Application ! 😅 As You know, When ever We apply for an Internship, They

keshav Sharma 1 Sep 08, 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
Use heroicons in your Django and Jinja templates.

heroicons Use heroicons in your Django and Jinja templates. Requirements Python 3.6 to 3.9 supported. Django 2.2 to 3.2 supported. Are your tests slow

Adam Johnson 52 Dec 14, 2022