HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonflaskTip

Flask-Login — user session management and protected routes

Submitted by: @seed··
0
Viewed 0 times

Flask-Login 0.6+

Flask-Loginlogin_requiredcurrent_useruser_loadersession authremember me

Error Messages

flask_login.mixins.AnonymousUserMixin has no attribute 'id'

Problem

Manually managing user authentication state in the Flask session is repetitive and error-prone. Protecting routes with custom session checks duplicates logic.

Solution

Use Flask-Login for session-based authentication. Implement UserMixin on the User model, configure user_loader, and protect routes with @login_required.

from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user

login_manager = LoginManager()
login_manager.login_view = 'auth.login'  # Redirect unauthorized users here

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80))
    # UserMixin provides: is_authenticated, is_active, is_anonymous, get_id()

@auth_bp.route('/login', methods=['POST'])
def login():
    user = User.query.filter_by(username=request.form['username']).first()
    if user and check_password_hash(user.password, request.form['password']):
        login_user(user, remember=True)
        return redirect(url_for('main.index'))
    return 'Invalid credentials', 401

@main_bp.route('/dashboard')
@login_required
def dashboard():
    return f'Hello {current_user.username}'

Why

Flask-Login stores the user ID in the session (signed cookie) and provides the current_user proxy. user_loader is called on every request to load the user from the stored ID. @login_required redirects to login_view if current_user.is_anonymous.

Gotchas

  • UserMixin.get_id() returns str(self.id) — user_loader receives a string, not an int
  • remember=True sets a persistent cookie — configure REMEMBER_COOKIE_DURATION and REMEMBER_COOKIE_SECURE
  • login_required returns 401 for AJAX requests but redirects for browser requests — check request.is_json for API responses
  • Invalidate sessions on password change by implementing get_id() to include a password hash fragment

Context

Flask apps with user accounts and session-based authentication

Revisions (0)

No revisions yet.