Secure login system with Flask and Python — banner illustration

Creating a secure login system is essential for protecting user data in web applications. Flask, a lightweight Python web framework, allows developers to build authentication systems efficiently while maintaining security best practices. In this guide, we’ll walk through the process of developing a secure login system using Flask, hashing passwords, and implementing user authentication. Along the way, we’ll add a little context so the choices you make are guided by both practicality and security.

Why Use Flask for User Authentication?

Flask is minimal, composable, and easy to reason about. You start with a small core and add exactly the tools you need—ORM, session handling, and authentication helpers—without the overhead of a large, opinionated framework. That flexibility is ideal when you want clear control over security decisions such as hashing algorithms, session policies, and database models.

  • Lightweight and Flexible: Allows for easy customization.
  • Security Features: Supports password hashing, session management, and authentication.
  • Integration with Databases: Works well with SQLite, PostgreSQL, and MySQL.

Prerequisites

Before getting started, install the required libraries:

pip install flask flask-sqlalchemy flask-login werkzeug

Step 1: Set Up the Flask Project

Create a project folder and a new Python file:

mkdir flask_login_system
cd flask_login_system
touch app.py

Step 2: Configure Flask and Database

Initialize Flask and configure SQLite as the database.

from flask import Flask, render_template, redirect, url_for, request, flash
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'

db = SQLAlchemy(app)

login_manager = LoginManager(app)
login_manager.login_view = "login"

Step 3: Create the User Model

Define a user model with password hashing.

from werkzeug.security import generate_password_hash, check_password_hash

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(150), unique=True, nullable=False)
    password = db.Column(db.String(150), nullable=False)

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

Step 4: Create the Registration Route

Allow users to register with a hashed password.

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        hashed_password = generate_password_hash(password, method='sha256')
        new_user = User(username=username, password=hashed_password)
        db.session.add(new_user)
        db.session.commit()

        flash('Registration successful!')
        return redirect(url_for('login'))

    return render_template('register.html')

Step 5: Create the Login Route

Authenticate users and manage sessions.

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        user = User.query.filter_by(username=username).first()
        if user and check_password_hash(user.password, password):
            login_user(user)
            return redirect(url_for('dashboard'))
        else:
            flash('Invalid username or password')

    return render_template('login.html')

Step 6: Create a Protected Dashboard

Ensure only logged-in users can access the dashboard.

@app.route('/dashboard')
@login_required
def dashboard():
    return "Welcome to your dashboard!"

Step 7: Create the Logout Route

Allow users to log out securely.

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('You have been logged out.')
    return redirect(url_for('login'))

Step 8: Running the Flask Application

Initialize the database and run the app:

if __name__ == '__main__':
    db.create_all()
    app.run(debug=True)

Best Practices for Secure Authentication

Keep your implementation simple but disciplined. Always hash passwords with a strong algorithm, enforce HTTPS in production, and keep secrets out of your codebase. Basic rate limiting on login endpoints and short, rotating session cookies go a long way to reducing risk.

  • Use Password Hashing: Never store plain-text passwords.
  • Implement Session Management: Use Flask-Login to handle authentication sessions.
  • Enable HTTPS: Encrypt data transmission using SSL certificates.
  • Limit Login Attempts: Prevent brute-force attacks.
  • Use Environment Variables: Store secret keys securely.

FAQs

Can I use PostgreSQL instead of SQLite?
Yes. Update the SQLAlchemy URI, for example: postgresql+psycopg2://user:password@host:5432/dbname.

How do I add email verification?
Use a mail library (e.g., Flask-Mail or a provider’s API) to send a tokenized link; confirm the token before activating the account.

Is Flask secure for production?
Yes—when paired with a WSGI server (Gunicorn/uWSGI), HTTPS, proper headers (HSTS), and secret management. Keep dependencies updated.

How can I add OAuth login?
Libraries like authlib or flask-dance provide Google, GitHub, and other providers with minimal setup.

Where should I store my SECRET_KEY and DB credentials?
Use environment variables or a secrets manager; never hard-code secrets in source control.

Related Posts