Password Management in Flask
Introduction
This article explains how to manage passwords securely in Flask applications, focusing on hashing passwords using bcrypt or Werkzeug and implementing password reset functionality.
Step 1: Installing Necessary Libraries
Install the required libraries for password management:
pip install flask flask-sqlalchemy flask-mail bcrypt
Step 2: Setting Up Flask and Database
Configure your Flask app and set up a database:
from flask import Flask, request, redirect, url_for, flash from flask_sqlalchemy import SQLAlchemy from flask_mail import Mail, Message from bcrypt import hashpw, gensalt, checkpw app = Flask(__name__) app.config['SECRET_KEY'] = 'your_secret_key' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db' app.config['MAIL_SERVER'] = 'smtp.gmail.com' app.config['MAIL_PORT'] = 587 app.config['MAIL_USE_TLS'] = True app.config['MAIL_USERNAME'] = 'your_email@gmail.com' app.config['MAIL_PASSWORD'] = 'your_email_password' db = SQLAlchemy(app) mail = Mail(app)
Step 3: Creating the User Model
Define a User model with fields for email and hashed password:
class User(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(120), unique=True, nullable=False) password = db.Column(db.String(128), nullable=False)
Create the database:
db.create_all()
Step 4: Hashing Passwords with bcrypt
Hash passwords before storing them in the database:
@app.route('/register', methods=['POST']) def register(): email = request.form.get('email') raw_password = request.form.get('password') hashed_password = hashpw(raw_password.encode('utf-8'), gensalt()) user = User(email=email, password=hashed_password) db.session.add(user) db.session.commit() flash('Registration successful!') return redirect(url_for('login'))
Check the password during login:
@app.route('/login', methods=['POST']) def login(): email = request.form.get('email') raw_password = request.form.get('password') user = User.query.filter_by(email=email).first() if user and checkpw(raw_password.encode('utf-8'), user.password): flash('Login successful!') return redirect(url_for('dashboard')) else: flash('Invalid email or password') return redirect(url_for('login'))
Step 5: Implementing Password Reset
Generate a password reset token and send it via email:
@app.route('/forgot-password', methods=['POST']) def forgot_password(): email = request.form.get('email') user = User.query.filter_by(email=email).first() if user: reset_token = hashpw(email.encode('utf-8'), gensalt()).decode('utf-8') reset_link = url_for('reset_password', token=reset_token, _external=True) msg = Message('Password Reset Request', recipients=[email]) msg.body = f'Click the link to reset your password: {reset_link}' mail.send(msg) flash('Password reset email sent!') else: flash('Email not registered') return redirect(url_for('login'))
Handle password reset requests:
@app.route('/reset-password/', methods=['GET', 'POST']) def reset_password(token): if request.method == 'POST': new_password = request.form.get('password') email = request.form.get('email') user = User.query.filter_by(email=email).first() if user: user.password = hashpw(new_password.encode('utf-8'), gensalt()) db.session.commit() flash('Password reset successful!') return redirect(url_for('login')) else: flash('Invalid token') return ''' <form method="POST"> Email: <input type="email" name="email"><br> New Password: <input type="password" name="password"><br> <button type="submit">Reset Password</button> </form> '''
Conclusion
This guide explains how to hash passwords securely and implement password reset functionality in Flask applications. Always hash passwords before storing them in the database to enhance security.