Content Index
- What is Flask-Login and what is it for?
- About Flask Login
- Install Flask Login
- ⚙️ Installation and basic configuration of the module
- Controllers and views: login, logout, and registration
- Creating the user model with SQLAlchemy
- Login and registration forms with Flask-WTF
- Templates
- Protecting routes with @login_required
- Remembering sessions and good security practices
- Common errors and how to debug them
- ❓ Frequently Asked Questions about Flask-Login
User authentication is one of the essential functions in any web application. In the Flask ecosystem, the Flask-Login extension facilitates all session management, logging in and out, and the "remember me" option.
When I built my first projects with Flask, I tried several extensions like Flask-User and Flask-Security, but I ended up choosing Flask-Login because it offers a perfect balance between simplicity and total control over the authentication flow.
Authentication is fundamental in systems like Flask-SocketIO for defining websockets.
You can use the Flask-Login module to control access. It provides user session management for Flask: logging in, logging out, and remembering sessions.
What is Flask-Login and what is it for?
Flask-Login is an official Flask extension that manages user sessions simply and securely. It allows you to:
- Easily log in and log out.
- Protect routes using the @login_required decorator.
- Implement the "remember me" function to keep the user authenticated.
- Detect the current user with current_user.
- Store the active user's ID in the Flask session and allow you to easily log in and log out.
- Allow you to restrict views to logged-in (or logged-out) users. (Login required)
- Handle the "remember me" functionality, which is usually complicated.
- Help protect your users' sessions from being stolen by cookie thieves.
Its greatest advantage is that it doesn't impose a specific database or user model. You decide how the user is stored and validated (e.g., with SQLAlchemy or MongoDB).
However, it will not:
- Impose a particular database or other storage method on you. You are completely in charge of how the user is loaded.
- Restrict you to using usernames and passwords, OpenID, or any other authentication method.
- Handle permissions beyond "logged in or not."
- Manage user registration or account recovery.
About Flask Login
Flask-Login is an extension for the Flask web framework that provides user session management, such as logging in, logging out, and session persistence. To use Flask-Login, we create a model for the user that defines the methods and parameters required by this extension, such as is_authenticated, is_active, and is_anonymous, and then initialize the extension in your Flask application.
Flask-Login is provided through an excellent package that allows us to handle the common tasks of logging in and out, in addition to remembering credentials for a long time.
It works in a simple way in which we need a user model and based on this we can compare credentials and log in:
With our authenticated user we can perform operations such as:
- Easily log out.
- Restrict the view to logged-in (or logged-out) users.
Install Flask Login
With our application created, let's install the package with:
$ pip install flask-loginThe first thing we need is to install the package, since as you should know at this point, Flask is a micro framework and brings the minimum and necessary to function; in essence, basic core functions, routing, security, and an HTML templating engine; for everything else, there is Mastercard or installing third-party packages, whether from Python or the framework itself.
⚙️ Installation and basic configuration of the module
Before starting, make sure you have your virtual environment activated:
$ pip install flask flask-login flask-wtf flask-sqlalchemyThe login_view parameter indicates the view to which the user is redirected if they try to access a protected route without being authenticated.
When I first implemented this, I found it useful to print the current_user statuses to understand how Flask-Login internally manages sessions.
Let's go to our __init__ in proyect/app/:
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app)And with this, we are ready to use it.
Controllers and views: login, logout, and registration
We are going to have a module or application called app:
proyect/app/user in which we will create the typical MVC in Flask applications:
from flask import Blueprint,session, render_template, request, redirect, url_for, flash, get_flashed_messages
from app.user.models import User
from app.user.forms import LoginForm, RegisterForm
from app import db, login_manager
from flask_login import current_user,login_user, login_required, logout_user
from werkzeug.security import generate_password_hash
userBp = Blueprint('user',__name__)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(user_id)
@userBp.route('/login', methods=('GET', 'POST'))
def login():
#print(current_user.name)
form = LoginForm(meta={'csrf':False})
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and user.check_password(form.password.data):
# registrar sesion
login_user(user, remember=True)
flash("Bienvenido de nuevo "+user.username)
print("Vien")
return redirect(url_for('chat.hello_world'))
else:
print("Malo")
flash("Usuario o contraseña incorrectos",'danger')
if form.errors:
print(form.errors)
flash(form.errors,'danger')
return render_template('user/login.html',form=form)
@userBp.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('user.login'))
@userBp.route('/register', methods=('GET', 'POST'))
def register():
print(session)
print(current_user)
form = RegisterForm(meta={'csrf':False})
if form.validate_on_submit():
if User.query.filter_by(username=form.username.data).first():
flash("El usuario ya existe en el sistema",'danger')
else:
#crear usuario
u = User()
u.name = form.username.data
u.username = form.username.data
u.password = generate_password_hash(form.password.data)
u.email = form.email.data
login_user(u, remember=True)
flash("Usuario creado con éxito")
return redirect(url_for('user.register'))
if form.errors:
flash(form.errors,'danger')
return render_template('user/register.html',form=form)
@login_required
def logout():
logout_user()
return redirect(url_for('user.login'))I should include personalized flash messages to improve the user experience, something as simple as "Session started successfully!" helps a lot in usability testing.
Creating the user model with SQLAlchemy
Define a user model that inherits from UserMixin, which adds the necessary methods (is_authenticated, get_id(), etc.):
from flask_login import UserMixin
from app import db
from werkzeug.security import check_password_hash,generate_password_hash
class User(db.Model,UserMixin):
id = db.Column(db.Integer, primary_key=True)
email= db.Column(db.String(100), unique=True)
username= db.Column(db.String(100), unique=True)
password= db.Column(db.String(400))
name= db.Column(db.String(100))
#__tablename__ = 'users'
def check_password(self, password):
return check_password_hash(self.password,password)Login and registration forms with Flask-WTF
Forms are handled with Flask-WTF, which simplifies validation:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, HiddenField
from wtforms.validators import InputRequired, EqualTo
class LoginForm(FlaskForm):
username = StringField('Usuario', validators=[InputRequired()])
password = PasswordField('Contraseña', validators=[InputRequired()])
class RegisterForm(FlaskForm):
username = StringField('Usuario', validators=[InputRequired()])
email = StringField('Email', validators=[InputRequired()])
password = PasswordField('Contraseña', validators=[InputRequired(),EqualTo('confirm')])
confirm = PasswordField('Repetir Contraseña')Templates
Login templates, /app/templates/user/login
<form action="{{ url_for('user.login') }}" method="POST">
<div class="form-group">
{{ form.username.label }}
{{ form.username(class="form-control") }}
</div>
<div class="form-group">
{{ form.password.label }}
{{ form.password(class="form-control") }}
</div>
<input class="btn btn-success" type="submit" value="Enviar">
</form>Register templates, /app/templates/user/register
<form action="{{ url_for('user.register') }}" method="POST">
<div class="form-group">
{{ form.username.label }}
{{ form.username(class="form-control") }}
</div>
<div class="form-group">
{{ form.email.label }}
{{ form.email(class="form-control") }}
</div>
<div class="form-group">
{{ form.password.label }}
{{ form.password(class="form-control") }}
</div>
<div class="form-group">
{{ form.confirm.label }}
{{ form.confirm(class="form-control") }}
</div>
<input class="btn btn-success" type="submit" value="Enviar">
</form>This example defines a user model that has an ID attribute, it also defines its view and route for logging in, logging in, registering, among others; protected routes are defined using the @login_required decorator, which ensures that only authenticated users can access the function. The logout route logs the user out and redirects them to the login page.
You can also customize Flask-Login's behavior using various configuration options, as you can see in the official documentation.
Protecting routes with @login_required
Once Flask-Login is configured, you can protect critical routes:
from flask_login import login_required
@app.route('/dashboard')
@login_required
def dashboard():
return "Bienvenido al panel"This ensures that only authenticated users can access it. If they are not, Flask-Login automatically redirects them to the login_view.
Remember that you can see the project source code here:
https://github.com/libredesarrollo/curso-flask-socketio
Or here:
https://github.com/libredesarrollo/curso-flask-base
And remember that we are not using styles:

Remember that this material is part of my complete Flask course and book.
Remembering sessions and good security practices
Flask-Login offers the option remember=True in login_user(), which creates a secure cookie that keeps the session active even if the browser is closed.
Recommended good practices:
- Use Flask-Talisman or Flask-SeaSurf to reinforce security.
- Always encrypt passwords with generate_password_hash.
- Invalidate sessions after password changes or logout.
- Avoid storing sensitive information in cookies.
When I developed my first authentication system, I learned that the simplicity of Flask-Login does not exempt you from applying security measures; that's why I always recommend accompanying it with HTTPS and session expiration policies.
Common errors and how to debug them
Error Probable Cause Solution
AttributeError: 'User' object has no attribute 'is_authenticated' Missing inheritance from UserMixin Add UserMixin to the model
login_user() does not maintain the session LoginManager was not initialized Check login_manager.init_app(app)
Infinite redirection to login login_view was not configured Define login_manager.login_view = 'user.login'
CSRF Token missing CSRF disabled in forms Activate protection in Flask-WTF
Conclusion: why Flask-Login is my preferred choice
Flask-Login is, without a doubt, the simplest and most flexible way to add authentication to your Flask projects.
It allows you to build robust systems without depending on heavy configurations or specific ORMs.
In my experience, combining Flask-Login + Flask-WTF + SQLAlchemy offers a complete, secure, and fully customizable flow.
If you are looking for total control and clarity in your code, Flask-Login is the ideal starting point.
❓ Frequently Asked Questions about Flask-Login
- Does Flask-Login handle user registration?
- No. It only controls sessions and authentication. You implement the registration yourself.
- How do I remember user sessions?
- Use login_user(user, remember=True) to create a persistent cookie.
- Can I use Flask-Login without a database?
- Yes, as long as your model implements the methods required by UserMixin.
- How do I redirect the user after login?
- Use redirect(url_for('desired_route')) right after login_user().
Learn how to send emails with Flask, which is ideal for sending notifications to the user.