User Login with Flask-Login

Flask-Login is an extension that manages user sessions, storing the logged-in user's identity in a signed cookie so your app remembers who someone is across requests.

Learn User Login with Flask-Login in our free Flask course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Flask course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll build the full login flow — verifying credentials, calling login_user , protecting routes with @login_required , and reading current_user in your views.

Before reaching for the extension, it helps to see what it does under the hood. A login is just this: verify a password, then remember the user's identity in the session (a signed cookie). Every later request reads that cookie to know who is logged in.

The runnable example below builds that flow with plain Flask session . A /login route checks credentials and stores the username; /dashboard is "protected" by checking the session; /logout clears it. This is exactly the machinery Flask-Login automates for you.

Output: 401 , then Logged in as ada , then Welcome to your dashboard, ada! , then Logged out , then 401 again — the session cookie is what carries the identity between requests.

The real extension replaces that manual bookkeeping with three pieces. First, your User model inherits from UserMixin , which supplies the properties Flask-Login expects. Second, a LoginManager is attached to the app. Third, a @login_manager.user_loader function tells Flask-Login how to fetch a user by ID on each request.

Here is the production setup. It is shown read-only because it relies on the flask_login package, but it maps one-to-one onto the runnable flow above.

With Flask-Login, @login_required wraps any view and returns a redirect (or 401) when no one is logged in. Inside a protected view, current_user is the live User object — you can read current_user.username , check current_user.is_authenticated , or branch on a role.

The runnable demo below reproduces @login_required and current_user with a tiny decorator over the core session, so you can watch a protected route reject an anonymous client and then greet a logged-in one.

Output: 401 for the anonymous request, then Account for Ada Lovelace (role: admin) once logged in. Swap g.current_user for Flask-Login's current_user and the code reads identically.

Complete the login flow. Replace each ___ so the user is remembered, the protected route checks the session, and logout clears it.

❌ "Missing user_loader" or current_user is always anonymous

You forgot the @login_manager.user_loader callback. Without it, Flask-Login cannot turn the id in the cookie back into a user, so current_user stays anonymous.

❌ RuntimeError: The session is unavailable / no secret key

Sessions are signed, so you must set app.secret_key . Without it, Flask cannot store or read the login cookie and raises an error.

Never store plaintext. Hash on registration with generate_password_hash and verify with check_password_hash before calling login_user .

Build an admin-only route that authorizes on top of authentication.

Lesson complete — your app can recognize its users!

You now understand the session-cookie login flow, how UserMixin and the user_loader power current_user , and how @login_required guards your routes.

🚀 Up next: Form Validation with Flask-WTF — collect login and registration data safely, with validators and CSRF protection.

Practice quiz

What does Flask-Login primarily manage for you?

  • database migrations
  • the user session and current_user
  • HTML templates
  • URL routing

Answer: the user session and current_user. It stores the user's id in the session and reloads them via current_user on each request.

Which function logs a user in?

  • login_user(user)
  • user.login()
  • session.login(user)
  • authenticate(user)

Answer: login_user(user). login_user(user) stores user.get_id() in the signed session cookie.

Which decorator blocks anonymous visitors from a route?

  • @require_auth
  • @authenticated
  • @login_required
  • @protected

Answer: @login_required. @login_required redirects or returns 401 when no user is logged in.

How do you read the currently logged-in user?

  • user

Flask-Login exposes current_user, the live User object, in views and templates.

What does UserMixin provide on your User model?

  • is_authenticated, is_active, is_anonymous, get_id()
  • a database table
  • password hashing
  • the login form HTML

Answer: is_authenticated, is_active, is_anonymous, get_id(). UserMixin supplies the properties Flask-Login expects from a user object.

What does the @login_manager.user_loader callback do?

  • renders the login page
  • loads a user by id from the session on each request
  • hashes the password
  • creates the session cookie

Answer: loads a user by id from the session on each request. user_loader turns the id stored in the cookie back into a full User object.

Which function ends the user's session?

  • session.end()
  • current_user.logout()
  • logout_user()
  • login_user(None)

Answer: logout_user(). logout_user() clears the logged-in user from the session.

What is stored in the cookie when you call login_user(user)?

  • the password hash
  • the whole User object
  • the username only
  • user.get_id()

Answer: user.get_id(). Only the user's id is stored; load_user rebuilds the full object each request.

How should passwords be verified at login?

  • check_password_hash against a stored hash
  • compare raw strings with ==
  • store them in the session
  • encode with base64

Answer: check_password_hash against a stored hash. Hash on registration with generate_password_hash and verify with check_password_hash.

What is the difference between authentication and authorization?

  • they are the same thing
  • authentication is 'who are you', authorization is 'are you allowed'
  • authorization happens first
  • authentication checks roles

Answer: authentication is 'who are you', authorization is 'are you allowed'. Authentication verifies identity; authorization checks permissions once identity is known.