Article
· Jan 9 9m read

Flask and Flask-Login: A Guide to Building Secure Web Applications

  Hi, Community!

Since this article is an overview of Flask Login, let's begin with Flask Introduction!

What is Flask?

In the realm of web development, Python has emerged as a formidable force, offering its versatility and robustness to create dynamic and scalable applications. For that reason, tools and services compatible with this language are in demand these days. Flask is a lightweight and easy-to-use web framework for Python. It stands out as a lightweight and user-friendly option. Its simplicity and flexibility have made it a popular choice for developers, particularly for creating smaller-scale applications. It is based on the Werkzeug toolkit and provides a simple but powerful API for building web applications. 
Unlike its full-stack counterparts, Flask provides a core set of features, focusing on URL routing, template rendering, and request handling. This minimalist approach makes Flask lightweight and easy to learn, allowing developers to build web applications quickly and without the burden of unnecessary complexity.

It also contains a rich ecosystem of extensions that provide additional functionality, such as database integration, user authentication, and form validation.


What is Flask-Login?

Since secure web development demands more than just a robust framework, user authentication and login management also play a crucial role in protecting sensitive data and preventing unauthorized access. This is where Flask-Login kicks in. It is an extension for Flask that simplifies the process of adding user authentication and login management of Flask applications.

Flask's flexibility unfolds to its extensibility. A rich ecosystem of extensions, including Flask-SQLAlchemy for database integration, Flask-WTF for form validation, and Flask-Mail for sending emails, provides additional functionality to cater to diverse application needs.

Flask-Login simplifies the process of adding user authentication to a Flask application, making it easy to protect your application's resources from unauthorized access. It provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users’ sessions over extended timespans.

Flask-Login provides several features, including the following:

  1. User Registration and Login: Flask-Login provides functions for registering new users and handling login requests.
  2. User Session Management: Flask-Login manages user sessions, ensuring that users remain logged in until they explicitly log out.
  3. Remember-Me Functionality: Flask-Login supports the "remember me" feature, allowing users to remain logged in across browser sessions.
  4. Logout Functionality: Flask-Login provides a straightforward logout mechanism for terminating user sessions.
  5. Role-Based Access Control (RBAC): Flask-Login can integrate with role-based access control (RBAC) systems to restrict access based on user roles.

Getting Started with Flask and Flask-Login

To begin working with Flask and Flask-Login, you will need to install the following dependencies:

pip install Flask Flask-Login flask_sqlalchemy sqlalchemy-iris

After installing the dependencies, you can create the basic application: the basic application:

from flask import Flask

# Create Flask application
app = Flask(__name__)

# Secret key for session management, replace with a random and secure key in a real application
app.config['SECRET_KEY'] = 'YOUR_SECRET_KEY'
# Define a route for the root path
@app.route("/")
def home():
    return render_template("index.html") 

# Run the application on port 5000
if __name__ == "__main__":
    app.run('0.0.0.0', port="4040", debug=True)

Below you can find the output of the above-written code:


User Model class and DB Connection

The user model is a Python class that represents a user in your application. It typically contains such attributes as the user's username, email address, and password. You will need to create a user model and define a method to load a user by their ID. Additionally, you will require DB to complete a model.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

#Get DB reference
db = SQLAlchemy()

# Define User model class
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(150), unique=True)
    username = db.Column(db.String(150), unique=True)
    password = db.Column(db.String(150))
  
    def __repr__(self):
        return f'{self.username}'
# Create Flask application    
app = Flask(__name__)

# Secret key for session management, replace with a random and secure key in a real application
# Replace with strong key
app.config['SECRET_KEY'] = 'YOUR_SECRET_KEY'
#Set IRIS connection parameters
DB_USER = "_SYSTEM"
DB_PASS = "SYS"
DB_URL = "localhost"
DB_PORT = '1972'
DB_NAMESPACE = "USER"
# Configure database connection using SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = f'iris://{DB_USER}:{DB_PASS}@{DB_URL}:{DB_PORT}/{DB_NAMESPACE}'
app.app_context().push()

# init database
db.init_app(app)
with app.app_context():
    db.create_all()

# Define a route for the root path
@app.route("/")
def home():
    return render_template("index.html") 

# Run the application on port 5000
if __name__ == "__main__":
    app.run('0.0.0.0', port="4040", debug=True)

The above-written code connects to IRIS and creates the table in IRIS DB illustrated below:


Apply Flask_login functionality

Flask-Login provides several functions for users to log in and log out. For instance, to log in as a user, you should call the login_user() function by passing in the user object as an argument. To log out a user, you can call the logout_user() function. To authentication,  remember to add @login_required decorator.
Check out the final app.py file below: 

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

#Get DB reference
db = SQLAlchemy()

# Define User model class
class User(db.Model,UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(150), unique=True)
    username = db.Column(db.String(150), unique=True)
    password = db.Column(db.String(150))
  
    def __repr__(self):
        return f'{self.username}'
# Create Flask application    
app = Flask(__name__)

# Secret key for session management, replace with a random and secure key in a real application
# Replace with strong key
app.config['SECRET_KEY'] = 'YOUR_SECRET_KEY'
# Create an instance of the LoginManager for handling user login/logout
login_manager = LoginManager()
login_manager.init_app(app)

#Set IRIS connection parameters
DB_USER = "_SYSTEM"
DB_PASS = "SYS"
DB_URL = "localhost"
DB_PORT = '1972'
DB_NAMESPACE = "USER"
# Configure database connection using SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = f'iris://{DB_USER}:{DB_PASS}@{DB_URL}:{DB_PORT}/{DB_NAMESPACE}'
app.app_context().push()

# init database
db.init_app(app)
with app.app_context():
    db.create_all()

# Assign Login View
login_manager = LoginManager()
# Redirect to the login page if authentication fails
login_manager.login_view = "login"
login_manager.init_app(app)

# Query user from the database based on user ID
@login_manager.user_loader
def load_user(user_id):
    # Query user from database based on user ID
    return User.query.get(user_id)

# Define a route for the root path
@app.route("/")
def home():
    return render_template("index.html") 

@app.route("/admin")
@login_required
def admin():
    return "This is the Admin Page. Authentication required"
#apply flask_login login functionality
@app.route("/login", methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        email = request.form.get("email")
        password = request.form.get("password")

        user = User.query.filter_by(email=email).first()
        if user:
            if user.password ==  password:
                login_user(user, remember=True)
                return redirect(url_for('home'))
            else:
                return "Incorrect password."
        else:
            return "Email does not exist."
    return render_template("login.html", user=current_user)

# Register user
@app.route("/signup", methods=['GET', 'POST'])
def signup():
    if request.method == 'POST':
        email = request.form.get("email")
        username = request.form.get("username")
        password1 = request.form.get("password")
        password2 = request.form.get("password2")

        email_exists = User.query.filter_by(email=email).first()
        username_exists = User.query.filter_by(username=username).first()
        # validation
        if email_exists:
            return "Email is already in use."
        elif username_exists:
            return "Username is already in use."
        elif password1 != password2:
            return "Password don\'t match!"
        elif len(username) < 2:
            return "Username is too short."
        elif len(password1) < 6:
            return "Password is too short."
        elif len(email) < 4:
            return "Email is not valid."
        else:
            new_user = User(email=email, username=username, password=password1)
            db.session.add(new_user)
            db.session.commit()
            login_user(new_user, remember=True)
            return redirect(url_for('home'))

    return render_template("signup.html", user=current_user)

@app.route("/logout")
@login_required
def logout():
    logout_user()
    return redirect(url_for("home"))

## Run the application on port 5000
if __name__ == "__main__":
    app.run('0.0.0.0', port="4040", debug=True)


You can explore Index.html, Login.html, and Signup.html templates used in the above-mentioned app.py file below:

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home</title>
</head>
<body>
    <h1>Welcome to the Home Page</h1>
    {% if current_user.is_authenticated %}
        <p>Hello, {{ current_user.username }}!</p>
        <p><a href="{{ url_for('logout') }}">Logout</a></p>
    {% else %}
        <p><a href="{{ url_for('login') }}">Login</a> or <a href="{{ url_for('signup') }}">Sign Up</a></p>
    {% endif %}   
</body>
</html>


Login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
</head>
<body>
    <h2>Login</h2>
    <form method="POST" action="{{ url_for('login') }}">
        <label for="email">Email:</label>
        <input type="text" id="email" name="email" required><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required><br>
        <button type="submit">Login</button>
    </form>
    <p>Don't have an account? <a href="{{ url_for('signup') }}">Sign Up</a></p>
</body>
</html>


Signup.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sign Up</title>
</head>
<body>
    <h2>Sign Up</h2>
    <form method="POST" action="{{ url_for('signup') }}">
        <label for="email">Email:</label>
        <input type="text" id="email" name="email" required><br>
        <label for="username">User name:</label>
        <input type="text" id="username" name="username" required><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required><br>
        <label for="password2">Confirm Password:</label>
        <input type="password" id="password2" name="password2" required><br>
        <button type="submit">Sign Up</button>
    </form>
    <p>Already have an account? <a href="{{ url_for('login') }}">Login</a></p>
</body>
</html>


 

Conclusion

Flask and Flask-Login are robust tools that can help you build secure web applications in Python. Flask provides a simple but powerful API for making web applications, and Flask-Login simplifies the process of adding user authentication and login management. Together, they make it easy to create secure and scalable web applications.

Thank you for reading!

Discussion (0)1
Log in or sign up to continue