D Dev Duniya
Back to Journal
9 min read

Flask MySQL Authentication Tutorial: Login, Register, Logout, and Dashboard

Ashish Yadav

Ashish Yadav

Published on Dev Duniya
Keep exploring
Compare the details before you buy.
Flask MySQL Authentication Tutorial: Login, Register, Logout, and Dashboard

In this comprehensive tutorial, we'll walk through building a complete authentication system with Flask and MySQL. You'll learn how to implement user registration, login functionality, protected dashboard access, and logout features - all while securely storing user data in a MySQL database.

Why Build Authentication with Flask and MySQL?

Flask is a lightweight Python web framework that's perfect for building web applications, while MySQL remains one of the most popular relational database systems. Combining these technologies gives you:

  • A secure way to manage user accounts
  • Scalable storage for user credentials
  • Python's simplicity with MySQL's reliability
  • Full control over your authentication flow

Prerequisites

Before we begin, make sure you have:

  • Python 3.6+ installed
  • MySQL server installed and running
  • Basic knowledge of Python and Flask
  • pip for installing Python packages

Setting Up the Project

First, let's create our project structure and install the necessary packages.

1. Create a project folder

mkdir flask-auth-tutorial
cd flask-auth-tutorial

2. Set up a virtual environment

python -m venv venv
source venv/bin/activate  # On Windows use `venv\Scripts\activate`

3. Install required packages

pip install flask flask-mysqldb flask-login passlib

Project Structure

Here's how we'll organize our files:

flask-auth-tutorial/
│
├── app.py                # Main application file
├── templates/            # HTML templates
│   ├── layout.html       # Base template
│   ├── login.html        # Login page
│   ├── register.html     # Registration page
│   └── dashboard.html    # Dashboard page
└── requirements.txt      # Dependencies

Database Setup

First, let's create our MySQL database and user table.

1. Connect to MySQL

mysql -u root -p

2. Create database and table

CREATE DATABASE flask_auth;
USE flask_auth;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Building the Flask Application

Now, let's create our Flask application with authentication functionality.

app.py

from flask import Flask, render_template, request, redirect, url_for, flash, session
from flask_mysqldb import MySQL
from passlib.hash import sha256_crypt
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user

app = Flask(__name__)

# MySQL Configuration
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = ''  # Enter your MySQL password here
app.config['MYSQL_DB'] = 'flask_auth'
app.config['MYSQL_CURSORCLASS'] = 'DictCursor'

# Secret Key
app.secret_key = 'your_secret_key_here'

# Initialize MySQL
mysql = MySQL(app)

# Flask-Login Configuration
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

class User(UserMixin):
    def __init__(self, id, username, email):
        self.id = id
        self.username = username
        self.email = email

@login_manager.user_loader
def load_user(user_id):
    cur = mysql.connection.cursor()
    cur.execute("SELECT * FROM users WHERE id = %s", (user_id,))
    user = cur.fetchone()
    cur.close()
    
    if user:
        return User(id=user['id'], username=user['username'], email=user['email'])
    return None

# Routes
@app.route('/')
def home():
    return render_template('home.html')

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        email = request.form['email']
        password = sha256_crypt.encrypt(request.form['password'])
        
        cur = mysql.connection.cursor()
        
        # Check if username or email already exists
        cur.execute("SELECT * FROM users WHERE username = %s OR email = %s", (username, email))
        existing_user = cur.fetchone()
        
        if existing_user:
            flash('Username or email already exists', 'danger')
            return render_template('register.html')
        
        # Insert new user
        cur.execute("INSERT INTO users (username, email, password) VALUES (%s, %s, %s)", 
                   (username, email, password))
        mysql.connection.commit()
        cur.close()
        
        flash('Registration successful! Please login.', 'success')
        return redirect(url_for('login'))
    
    return render_template('register.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password_candidate = request.form['password']
        
        cur = mysql.connection.cursor()
        
        # Get user by username
        result = cur.execute("SELECT * FROM users WHERE username = %s", [username])
        
        if result > 0:
            data = cur.fetchone()
            password = data['password']
            
            # Compare passwords
            if sha256_crypt.verify(password_candidate, password):
                user = User(id=data['id'], username=data['username'], email=data['email'])
                login_user(user)
                
                flash('You are now logged in', 'success')
                return redirect(url_for('dashboard'))
            else:
                flash('Invalid password', 'danger')
                return render_template('login.html')
        else:
            flash('Username not found', 'danger')
            return render_template('login.html')
        
        cur.close()
    
    return render_template('login.html')

@app.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html', username=current_user.username)

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('You are now logged out', 'success')
    return redirect(url_for('login'))

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

Creating the HTML Templates

Now let's create our templates for the different pages.

templates/layout.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flask Auth System</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container">
            <a class="navbar-brand" href="/">Flask Auth</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ms-auto">
                    {% if current_user.is_authenticated %}
                    <li class="nav-item">
                        <a class="nav-link" href="{{ url_for('dashboard') }}">Dashboard</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{{ url_for('logout') }}">Logout</a>
                    </li>
                    {% else %}
                    <li class="nav-item">
                        <a class="nav-link" href="{{ url_for('login') }}">Login</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{{ url_for('register') }}">Register</a>
                    </li>
                    {% endif %}
                </ul>
            </div>
        </div>
    </nav>

    <div class="container mt-4">
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                {% for category, message in messages %}
                    <div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
                        {{ message }}
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                    </div>
                {% endfor %}
            {% endif %}
        {% endwith %}

        {% block content %}{% endblock %}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

templates/login.html

{% extends "layout.html" %}

{% block content %}
<div class="row justify-content-center">
    <div class="col-md-6">
        <div class="card">
            <div class="card-header">
                <h4>Login</h4>
            </div>
            <div class="card-body">
                <form action="{{ url_for('login') }}" method="POST">
                    <div class="form-group mb-3">
                        <label for="username">Username</label>
                        <input type="text" name="username" id="username" class="form-control" required>
                    </div>
                    <div class="form-group mb-3">
                        <label for="password">Password</label>
                        <input type="password" name="password" id="password" class="form-control" required>
                    </div>
                    <button type="submit" class="btn btn-primary">Login</button>
                </form>
                <p class="mt-3">Don't have an account? <a href="{{ url_for('register') }}">Register here</a></p>
            </div>
        </div>
    </div>
</div>
{% endblock %}

templates/register.html

{% extends "layout.html" %}

{% block content %}
<div class="row justify-content-center">
    <div class="col-md-6">
        <div class="card">
            <div class="card-header">
                <h4>Register</h4>
            </div>
            <div class="card-body">
                <form action="{{ url_for('register') }}" method="POST">
                    <div class="form-group mb-3">
                        <label for="username">Username</label>
                        <input type="text" name="username" id="username" class="form-control" required>
                    </div>
                    <div class="form-group mb-3">
                        <label for="email">Email</label>
                        <input type="email" name="email" id="email" class="form-control" required>
                    </div>
                    <div class="form-group mb-3">
                        <label for="password">Password</label>
                        <input type="password" name="password" id="password" class="form-control" required>
                    </div>
                    <button type="submit" class="btn btn-primary">Register</button>
                </form>
                <p class="mt-3">Already have an account? <a href="{{ url_for('login') }}">Login here</a></p>
            </div>
        </div>
    </div>
</div>
{% endblock %}

templates/dashboard.html

{% extends "layout.html" %}

{% block content %}
<div class="row justify-content-center">
    <div class="col-md-8">
        <div class="card">
            <div class="card-header">
                <h4>Welcome to Your Dashboard, {{ username }}!</h4>
            </div>
            <div class="card-body">
                <p>This is your protected dashboard page. Only authenticated users can access this page.</p>
                <p>You can implement any content here that should be visible to logged-in users only.</p>
            </div>
        </div>
    </div>
</div>
{% endblock %}

Running the Application

To start your Flask application, run:

python app.py

Then open your browser and navigate to http://localhost:5000.

Key Features Explained

1. User Registration

  • Collects username, email, and password
  • Hashes password using SHA-256 before storage
  • Checks for existing username/email to prevent duplicates
  • Stores user securely in MySQL database

2. User Login

  • Verifies username exists in database
  • Compares hashed password with user input
  • Uses Flask-Login to manage user sessions
  • Redirects to protected dashboard on success

3. Protected Dashboard

  • Requires authentication to access
  • Displays personalized welcome message
  • Demonstrates route protection with @login_required

4. User Logout

  • Ends the user session
  • Clears authentication cookies
  • Redirects to login page with success message

Security Considerations

  1. Password Hashing: We use passlib with SHA-256 to securely hash passwords before storing them.

  2. Session Management: Flask-Login handles session management securely.

  3. CSRF Protection: While not shown in this basic example, consider implementing CSRF protection for production.

  4. SQL Injection Prevention: Using parameterized queries helps prevent SQL injection.

  5. HTTPS: Always use HTTPS in production to encrypt data in transit.

Extending the Application

Here are some ways you can extend this basic authentication system:

  1. Email Verification: Add email confirmation before allowing login.

  2. Password Reset: Implement a password reset functionality.

  3. User Roles: Add roles (admin, user, etc.) with different permissions.

  4. Profile Management: Allow users to edit their profiles.

  5. Remember Me: Implement "remember me" functionality for persistent sessions.

Troubleshooting Common Issues

  1. MySQL Connection Errors: Ensure MySQL is running and credentials in app.py are correct.

  2. Table Not Found: Verify you created the users table in the flask_auth database.

  3. Module Not Found: Make sure you installed all required packages with pip.

  4. Login Not Persisting: Check your secret key is set and consistent.

  5. Password Verification Failing: Ensure you're using the same hashing method consistently.

Conclusion

In this tutorial, we've built a complete Flask authentication system with MySQL that includes:

  • User registration with secure password storage
  • Login functionality with session management
  • Protected dashboard page
  • Logout capability

This foundation can be extended to build more complex web applications with user authentication. The combination of Flask and MySQL provides a robust yet flexible system that can scale as your needs grow.

Remember to always prioritize security when dealing with user authentication, especially in production environments. Consider adding additional layers of security like rate limiting, brute force protection, and more sophisticated password policies for real-world applications.

From the product catalog

Explore device specifications

Specification cards update automatically from published catalog products, grouped by brand.

Apple specifications

Explore Apple devices →
Apple Apple MacBook Pro 14-inch
Apple Apple MacBook Pro 14-inch specifications

Experience unrivaled performance with the latest Apple MacBook Pro, available in 14-inch and 16-inch models powered by the revolutionary M6, M5 Pro, and M5 Max chips. Built for Apple Intelligence, these powerhouse laptops feature advanced Thunderbolt 5 ports, Wi-Fi 7, and optional Nano-texture displays for minimal glare. Maximize your creative potential with up to 128GB of unified memory in a sleek Space Black or Silver finish.

Display size
14-inch
Screen Type
Standard display (low reflectivity) or Nano-texture display (reduces reflections and glare in bright lighting)
External Display Support
Support for up to three external displays (M5 Pro) / Support for up to four external displays (M5 Max)
M6 Chip
12‑core CPU, 12‑core GPU, Dual 16‑core Neural Engine
See all specifications →
Apple Apple MacBook Pro 16-inch
Apple Apple MacBook Pro 16-inch specifications

Experience unrivaled performance with the latest Apple MacBook Pro, available in 14-inch and 16-inch models powered by the revolutionary M6, M5 Pro, and M5 Max chips. Built for Apple Intelligence, these powerhouse laptops feature advanced Thunderbolt 5 ports, Wi-Fi 7, and optional Nano-texture displays for minimal glare. Maximize your creative potential with up to 128GB of unified memory in a sleek Space Black or Silver finish.

Display size
16-inch
Screen Type
Standard display (low reflectivity) or Nano-texture display (reduces reflections and glare in bright lighting)
External Display Support
Support for up to three external displays (M5 Pro) Support for up to four external displays (M5 Max)
M5 Pro Chip
18‑core CPU, 20‑core GPU, 16‑core Neural Engine
See all specifications →
Apple Apple iPhone Duo
Apple Apple iPhone Duo specifications

Apple iPhone Duo is a new-generation iPhone model focused on a sleek design, powerful performance, and everyday usability. Explore iPhone Duo specifications, features, display, cameras, battery, and expected price in the USA. Get the latest information about Apple iPhone Duo and its key features. Compare iPhone Duo with other popular Apple iPhone models.

Size (inches)
Open: 4.64 x 6.48 x 0.21 Closed: 4.64 x 3.31 x 0.44
Weight (ounces)
8.96
Display size (inches)
Inner: 7.6-inch (diagonal) all-screen OLED folding display Outer: 5.4-inch (diagonal) all-screen OLED display
Resolution (pixels)
Inner: 1878-by-2670-pixel resolution at 430 ppi Outer: 1398-by-2034-pixel resolution at 460 ppi
See all specifications →
Apple Apple iPhone 18 Pro Max
Apple Apple iPhone 18 Pro Max specifications

Apple iPhone 18 Pro Max is a high-end flagship smartphone designed for powerful performance and advanced photography. Explore iPhone 18 Pro Max specifications, features, display, cameras, battery, and expected price in the USA. Discover the latest upgrades and key features of Apple’s largest Pro iPhone. Compare iPhone 18 Pro Max with other premium flagship smartphones.

Size (inches)
6.43 x 3.07 x 0.34
Weight (ounces)
8.78
Display size (inches)
6.9-inch (diagonal) all-screen OLED display
Resolution (pixels)
2868-by-1320-pixel resolution at 460 ppi
See all specifications →
Apple Apple iPhone 18 Pro
Apple Apple iPhone 18 Pro specifications

Apple iPhone 18 Pro is a premium flagship smartphone with advanced performance and an upgraded camera system. Explore iPhone 18 Pro specifications, features, display, cameras, battery, and expected price in the USA. Get the latest details about Apple’s new Pro model and its key upgrades. Compare iPhone 18 Pro features with other flagship smartphones.

Size (inches)
5.91 x 2.83 x 0.34
Weight (ounces)
7.44
Display size (inches)
6.3-inch (diagonal) all-screen OLED display
Resolution (pixels)
2622-by-1206-pixel resolution at 460 ppi
See all specifications →

Google specifications

Explore Google devices →
Google Google Pixel 12
Google Google Pixel 12 specifications

Upgrade to the Google Pixel 12, an advanced 5G AI smartphone. Experience seamless performance powered by the custom Google Tensor G7 processor. Enjoy a stunning 6.3-inch OLED Actua display and take flawless photos with the powerful 50MP dual-camera system. Built with an adaptive all-day battery and seamless Google Gemini AI integration, it is the perfect unlocked device for everyday brilliance.

Size (inches)
6.02 x 2.83 x 0.34
Weight (ounces)
6.95
Display size (inches)
6.3-inch (diagonal) OLED display
Resolution (pixels)
1080 x 2424 pixels
See all specifications →
Google Google Pixel 12 Pro
Google Google Pixel 12 Pro specifications

Discover the new Google Pixel 12 Pro, the ultimate 5G AI smartphone. Powered by the next-generation Google Tensor G7 chip and built-in Gemini AI, it delivers blazing-fast performance. Capture professional-grade photos with the advanced 50MP Pro Triple Camera system featuring 5x optical zoom. Complete with a stunning 6.3-inch Super Actua display, all-day adaptive battery, and a premium titanium frame. Upgrade to the smartest Android phone today.

Size (inches)
6.02 x 2.83 x 0.33
Weight (ounces)
7.3
Display size (inches)
6.31-inch LTPO OLED display
Resolution (pixels)
2856 x 1280 pixels
See all specifications →
Google Google Pixel 12 Pro XL
Google Google Pixel 12 Pro XL specifications

Go bigger with the Google Pixel 12 Pro XL, the ultimate large-screen 5G AI smartphone. It boasts a massive 6.8-inch OLED display and the lightning-fast Google Tensor G7 chip. Capture master-level photography using the 50MP Pro Triple Camera setup. Equipped with a massive 5500mAh battery for extended endurance and fast 67W charging, this unlocked flagship redefines premium power.

Size (inches)
6.43 x 3.07 x 0.34
Weight (ounces)
8.18
Display size (inches)
6.8-inch LTPO OLED Super Actua display
Resolution (pixels)
2992 x 1344 pixels
See all specifications →
Google Google Pixel 12 Pro Fold
Google Google Pixel 12 Pro Fold specifications

Transform your mobile experience with the Google Pixel 12 Pro Fold. This unlocked 5G AI foldable smartphone unfolds into a gorgeous 8-inch dual-UTG inner OLED display for next-level multitasking and entertainment. Powered by the Google Tensor G7 chip, it features flexible triple-camera photography, advanced Gemini AI, and a highly durable folding hinge design.

Size (inches) - Unfolded
6.24 x 5.64 x 0.16
Size (inches) - Folded
6.24 x 2.87 x 0.35
Weight (ounces)
7.58
Main Display
8.0-inch Foldable LTPO OLED, 120Hz
See all specifications →

Samsung specifications

Explore Samsung devices →