Blog Logo

11-Jan-2024 ~ 3 min read

Flask-Login Moving Parts


Table of Contents

1. Introduction

Flask-Login is a Flask extension that manages the user authentication process for Flask applications. It provides a login manager that handles the entire user authentication process, including session management, hashing, and authentication. In this article, we’ll walk through the moving parts of Flask-Login and how they work together to provide a seamless user authentication experience.

2. Prerequisites

Before we begin, ensure that you have the following:

  • A machine running Ubuntu 22.04.
  • Terminal access.

3. Sequence of operations

  1. The user navigates to http://localhost:5000/login by clicking on the “Login” link. The handler for this route renders the login template.

  2. The user enters the username and password in the login form and presses the “Submit” button. The same handler is invoked again, but now the request method is POST.

  3. The handler validates the credentials submitted with the form, and then invokes Flask-Login’s login_user() function to log the user in.

  4. The login_user() function writes the ID of the user to the user session. By default, user sessions are stored in the client-side cookies that are cryptographically signed with the configured application’s secret key. Any tampering with the cookie will render the signature invalid, and the session will be rejected.

  5. The view function returns with a redirect to the home page.

  6. The broweser receives the redirect and sends a new GET request to the home page.

  7. The home page view function is invoked and it triggers rendering of the home page template.

  8. During rendering of the Jinja2 templates, a reference to Flask-Login’s current_user appears for first time.

  9. The current_user context variable does not have a value assigned for this request yet, so it invokes Flask-Login’s internal function _get_user() to find who the user is.

  10. The _get_user() function checks if there is a user ID stored in the user session. If there isn’t one, it returns an instance of Flask-Login’s AnonymousUser. If there is an ID, it invokes the function that application registered with the user_loader decorator, passing the ID as a parameter.

  11. The application’s user_loader function queries the database and returns the User object, which is then assigned to the current_user context variable.

  12. The template is rendered with the current_user variable set to the User object.

The login_required decorator builds on top of the current_user context variable by only allowing the decorated view function to run when the expression current_user.is_authenticated is True. The logout_user() function simply deletes the user ID from the session.

Source: Inspired by Flask Web Development, 2nd Edition by Miguel Grinberg