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.