Flask-Login Moving Parts

Understand Flask-Login authentication flow step-by-step. Learn how sessions, cookies, and user_loader work together. Clear explanations with sequence diagrams.

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

About the Author

Ashish Anand

Ashish Anand

Founder & Lead Developer

Full-stack developer with 10+ years experience in Python, JavaScript, and DevOps. Creator of DevGuide.dev. Previously worked at Microsoft. Specializes in developer tools and automation.