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.





Advertisement