How to Create a Password reset in Flask Python
By: Digin Antony
Tags: Passwords, Flask Framework, Password Reset, Flask, Python

Flask is a micro web Framework written in Python. It is classified as a micro frameworks because it does not require particular tools or libraries.It has no database abstraction layer, form validation, or any other components where pre-existing third-party libraries provide common functions. However, Flask supports extensions that can add application features as if they were implemented in Flask itself. Extensions exist for object-relational mappers, form validation, upload handling, various open authentication technologies and several common framework related tools.

Password reset is important requirement if you are dealing with websites or application with user managements so their is two options we can use flask password reset library or create one your own I personally recommend create one your own so what are requirement create an password reset library.

we need password reset handler function

unique OTP or Link generator

keep session that track lifespan of OTP

Here We implement password reset request manager for application that communicate with REST-API

importing Library's

from flask import Flask,url_for,request,abort,jsonify

from datetime import datetime

import json

import re,os,time

import threading

also import Your database service library connect to your db here we use custom database library Chameleon DB is NOSQL developed for robust data management

Assume that we store users login information as email and password in document format, first we need an unique OTP generator with required length create function get_unique_id(email,no_digits=8) which take two arguments email of user no digits of otp default is set to 8 digits you wanted to generate

def get_unique_id(email,no_digits=8):

number= str(int(abs(hash(email))+time.time()))

if len(number)<no_digits:

number=number+str(random(no_digits-len(number)))

return number[:no_digits]

The above function create unique id using continuously changing time and hash code of email in order to avoid repetition of same otp.

Next we need a timer function that keep track of lifespan of otp you generated after a specified time period the email and its associated otp is cleared from database here we use database collection to save details of users they requested for forgot password called forgot_users after the lifespan of otp it is cleared form database we use create timer function to keep track of life span of otp.

def create_timer(email,unid,seconds=5):

while True:

time.sleep(60*seconds)

db.forgot_users.delete({"email":email,"otp":unid})

#deleting otp form database

db.commit()

print({email:unid},"is removed")

break

Next we need a password reset request handler which validate email of user request for password request and ensures that same user is not request for multiple password request (optional)create an unique id (OTP) and save to forgot_users collection with email of requested user and sent to user by means of SMS or email up to your convenience create a thread that monitor the lifespan of your otp automatically remove it from db after its life span.



def pwd_reset():

if not request.json:

return jsonify({"message":"Invalid Requst Format"})

inputs=request.json

try:

email=inputs['email']

except:

return jsonify({"message":"Not all argument Included"})

if len(db.users.find({"email":email}))==1:

if db.forgot_users.find({"$exists":{email:1}}):

return jsonify({"message":"The User allredy requested for password reset"})

unid=get_unique_id(email)

db.forgot_users.insert({"email":email,"otp":unid})

db.commit()

#Your logic to sent OTP to sent to user email or SMS

threading.Thread(target=create_timer,args=(email,unid,1,)).start()

return{"sucess":unid} #REST response to application to verify at client side

else:

return jsonify({"message":"requested User is Not Present"}) @app .route('/password_reset',methods=['POST'])def pwd_reset():if not request.json:return jsonify({"message":"Invalid Requst Format"})inputs=request.jsontry:email=inputs['email']except:return jsonify({"message":"Not all argument Included"})if len(db.users.find({"email":email}))==1:if db.forgot_users.find({"$exists":{email:1}}):return jsonify({"message":"The User allredy requested for password reset"})unid=get_unique_id(email)db.forgot_users.insert({"email":email,"otp":unid})db.commit()threading.Thread(target=create_timer,args=(email,unid,1,)).start()return{"sucess":unid}else:return jsonify({"message":"requested User is Not Present"})

So we sent an OTP to user to reset their password next we need an password reset validating function which verify the otp and corresponding email is correct and new entered password match password requirements and update new password of corresponding email to database and return error if the otp is not matched or otp life span is expired



def pwd_reset_verify():

if not request.json:

return jsonify({"message":"Invalid Requst Format"})

inputs=request.json

try:

email=inputs['email']

otp=inputs['otp']

new_password=inputs['password']

except:

return jsonify({"message":"Not all argument Included"})

if len(db.users.find({"email":email}))==1:

if len(db.forgot_users.find({"$exists":{email:1}}))==1:

try:

if not check_password(new_password): #check_password verify password meet requirements

return {"message":" password is not in porper format"}

if len(db.forgot_users.find({"email":email,"otp":otp}))==1:

db.users.Update({"email":email},{"$set":{"password":new_password}})#updating new password

except Exception as e:

return jsonify({"message":"Invalid OTP"})

return jsonify({"message":"Verified"})

else:

return jsonify({"message":"Session Experied"})

else:

return jsonify({"message":"requested User is Not Present"}) @app .route('/password_resetverify',methods=['POST'])def pwd_reset_verify():if not request.json:return jsonify({"message":"Invalid Requst Format"})inputs=request.jsontry:email=inputs['email']otp=inputs['otp']new_password=inputs['password']except:return jsonify({"message":"Not all argument Included"})if len(db.users.find({"email":email}))==1:if len(db.forgot_users.find({"$exists":{email:1}}))==1:try:if not check_password(new_password):return {"message":" password is not in porper format"}if len(db.forgot_users.find({"email":email,"otp":otp}))==1:db.users.Update({"email":email},{"$set":{"password":new_password}})except Exception as e:return jsonify({"message":"Invalid OTP"})return jsonify({"message":"Verified"})else:return jsonify({"message":"Session Experied"})else:return jsonify({"message":"requested User is Not Present"})

S ummary

This article outlined the how to implement password rest functio along with flask framework in short, relevant and focused manner. I genuinely hope it has helped someone get a better understanding of working of password reset.

I believe I have concentrated on the must-know topics that are absolutely required to be understood. This knowledge is sufficient to write your own python password reset program for any other web development frameworks like Django,web2py,bottle etc..

Thanks for reading this article! Leave a comment below if you have any questions. Be sure to sign up to get the latest tips, tricks, and news about writing python programs and other web development technologies etc. to share your comments and ideas and connect with other writers.