Kritim Yantra
Feb 22, 2025
Flask is a lightweight and flexible Python web framework that is perfect for building web applications, from simple to complex. In this article, we will walk you through the process of creating a user authentication system in Flask, including login, registration, and logout functionality. We will also ensure that the code is premium-quality and the GUI is visually appealing. By the end of this article, you will have a fully functional authentication system that you can integrate into any Flask project.
Flask is a micro web framework written in Python. It is classified as a microframework because it does not require particular tools or libraries. It has no database abstraction layer, form validation, or any other components where pre-existing third-party libraries provide common functions. However, Flask supports extensions that can add application features as if they were implemented in Flask itself.
In this article, we will use Flask to create a user authentication system that allows users to register, log in, and log out. We will also use Flask extensions like Flask-SQLAlchemy for database management, Flask-WTF for form handling, and Flask-Login for managing user sessions.
Before we start coding, we need to set up the Flask environment. Here’s how you can do it:
Make sure you have Python installed on your system. You can download it from the official Python website.
It’s a good practice to create a virtual environment for your Flask project. This will help you manage dependencies and avoid conflicts with other projects.
python3 -m venv myflaskenv
Activate the virtual environment using the following command:
myflaskenv\Scripts\activate
source myflaskenv/bin/activate
Now, install Flask and the necessary extensions:
pip install Flask Flask-SQLAlchemy Flask-WTF Flask-Login
Let’s create the basic structure of our Flask application:
myflaskapp/
│
├── app/
│ ├── __init__.py
│ ├── models.py
│ ├── routes.py
│ ├── forms.py
│ ├── templates/
│ │ ├── base.html
│ │ ├── register.html
│ │ ├── login.html
│ │ ├── index.html
│
├── config.py
├── run.py
In app/__init__.py, initialize the Flask application:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
db = SQLAlchemy()
login_manager = LoginManager()
def create_app():
app = Flask(__name__)
app.config.from_object('config.Config')
db.init_app(app)
login_manager.init_app(app)
# Import and register the Blueprint
from app.routes import auth
app.register_blueprint(auth)
with app.app_context():
db.create_all()
return app
In config.py, add the configuration settings:
import os
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'your-secret-key'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///site.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
In run.py, create the entry point for the application:
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run(debug=True)
In app/models.py, define the User model:
from app import db, login_manager
from flask_login import UserMixin
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
def __repr__(self):
return f"User('{self.username}', '{self.email}')"
In app/forms.py, create the registration form using Flask-WTF:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualTo
class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sign Up')
In app/routes.py, create the route for user registration:
from flask import Blueprint, render_template, redirect, url_for, flash
from app.forms import RegistrationForm, LoginForm
from app.models import User
from app import db, login_manager
from flask_login import login_user, current_user, logout_user
# Create a Blueprint for the routes
auth = Blueprint('auth', __name__)
@auth.route('/')
def home():
return render_template('index.html', title='Home')
@auth.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data, password=form.password.data)
db.session.add(user)
db.session.commit()
flash('Your account has been created! You are now able to log in', 'success')
return redirect(url_for('auth.login'))
return render_template('register.html', title='Register', form=form)
In app/templates/register.html, create the registration form template:
{% extends "base.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Join Today</legend>
<div class="form-group">
{{ form.username.label(class="form-control-label") }}
{{ form.username(class="form-control form-control-lg") }}
</div>
<div class="form-group">
{{ form.email.label(class="form-control-label") }}
{{ form.email(class="form-control form-control-lg") }}
</div>
<div class="form-group">
{{ form.password.label(class="form-control-label") }}
{{ form.password(class="form-control form-control-lg") }}
</div>
<div class="form-group">
{{ form.confirm_password.label(class="form-control-label") }}
{{ form.confirm_password(class="form-control form-control-lg") }}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
<div class="border-top pt-3">
<small class="text-muted">
Already Have An Account? <a class="ml-2" href="{{ url_for('auth.login') }}">Sign In</a>
</small>
</div>
{% endblock content %}
In app/forms.py, create the login form:
class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Login')
In app/routes.py, create the route for user login:
@auth.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and user.password == form.password.data:
login_user(user)
return redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check email and password', 'danger')
return render_template('login.html', title='Login', form=form)
In app/templates/login.html, create the login form template:
{% extends "base.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Log In</legend>
<div class="form-group">
{{ form.email.label(class="form-control-label") }}
{{ form.email(class="form-control form-control-lg") }}
</div>
<div class="form-group">
{{ form.password.label(class="form-control-label") }}
{{ form.password(class="form-control form-control-lg") }}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
<div class="border-top pt-3">
<small class="text-muted">
Need An Account? <a class="ml-2" href="{{ url_for('auth.register') }}">Sign Up Now</a>
</small>
</div>
{% endblock content %}
In app/routes.py, create the route for user logout:
@auth.route('/logout')
def logout():
logout_user()
return redirect(url_for('home'))
In app/templates/base.html, add a logout link:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{{ url_for('auth.home') }}">FlaskAuth</a>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
{% if current_user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.logout') }}">Logout</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.login') }}">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.register') }}">Register</a>
</li>
{% endif %}
</ul>
</div>
</nav>
In your templates folder, create a new file called index.html. This will be the template for your homepage.
{% extends "base.html" %}
{% block content %}
<div class="content-section">
<h1>Welcome to FlaskAuth</h1>
<p>This is the home page of the application.</p>
{% if current_user.is_authenticated %}
<p>You are logged in as {{ current_user.username }}.</p>
{% else %}
<p>Please <a href="{{ url_for('auth.login') }}">log in</a> or <a href="{{ url_for('auth.register') }}">register</a> to get started.</p>
{% endif %}
</div>
{% endblock content %}
To make the application visually appealing, we will use Bootstrap. You can include Bootstrap in your base.html:
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FlaskAuth</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{{ url_for('auth.home') }}">FlaskAuth</a>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
{% if current_user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.logout') }}">Logout</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.login') }}">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.register') }}">Register</a>
</li>
{% endif %}
</ul>
</div>
</nav>
<div class="container">
{% block content %}{% endblock %}
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
Run the application using:
python run.py
Visit http://127.0.0.1:5000/ in your browser and test the registration, login, and logout functionality.
In this article, we have covered how to create a user authentication system in Flask, including registration, login, and logout functionality. We also enhanced the GUI using Bootstrap and discussed some security best practices. This authentication system can be integrated into any Flask project, providing a solid foundation for user management.
By following this guide, you should now have a fully functional Flask application with user authentication. You can further extend this application by adding features like password reset, email verification, and user roles.
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google