Flask-Login

Intermedio
Flask
Flask
Actualizado: 20/06/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

Configuración Flask-Login

Flask-Login es una extensión que simplifica la gestión de sesiones de usuario en aplicaciones web Flask. Esta biblioteca maneja automáticamente las tareas comunes de autenticación como recordar qué usuarios han iniciado sesión, proteger vistas que requieren autenticación y gestionar el ciclo de vida de las sesiones.

La configuración inicial requiere instalar la extensión y establecer algunos componentes fundamentales que trabajarán en conjunto con nuestros modelos de usuario existentes.

Instalación y configuración básica

Para comenzar, instalamos Flask-Login mediante pip:

pip install Flask-Login

Una vez instalada, necesitamos configurar la extensión en nuestra aplicación Flask. La configuración básica requiere inicializar el LoginManager y establecer una clave secreta para las sesiones:

from flask import Flask
from flask_login import LoginManager

app = Flask(__name__)
app.config['SECRET_KEY'] = 'tu-clave-secreta-muy-segura'

# Inicializar LoginManager
login_manager = LoginManager()
login_manager.init_app(app)

# Configurar la vista de login
login_manager.login_view = 'login'
login_manager.login_message = 'Debes iniciar sesión para acceder a esta página.'

El LoginManager actúa como el coordinador central de todas las operaciones de autenticación. La propiedad login_view especifica qué ruta debe mostrar el formulario de inicio de sesión cuando un usuario no autenticado intenta acceder a una página protegida.

Adaptación del modelo de usuario

Flask-Login requiere que nuestro modelo de usuario implemente ciertos métodos específicos. La forma más sencilla es heredar de UserMixin, que proporciona implementaciones predeterminadas:

from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin

db = SQLAlchemy(app)

class Usuario(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password_hash = db.Column(db.String(255), nullable=False)
    activo = db.Column(db.Boolean, default=True)
    
    def __repr__(self):
        return f'<Usuario {self.email}>'

UserMixin proporciona automáticamente los métodos requeridos por Flask-Login:

  • is_authenticated: Devuelve True si el usuario ha proporcionado credenciales válidas
  • is_active: Devuelve True si la cuenta del usuario está activa
  • is_anonymous: Devuelve False para usuarios reales, True para usuarios anónimos
  • get_id(): Devuelve un identificador único para el usuario como string

Función de carga de usuario

Flask-Login necesita saber cómo cargar un usuario desde la base de datos usando su identificador. Esto se configura mediante el decorador user_loader:

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

Esta función se ejecuta automáticamente cuando Flask-Login necesita recuperar información del usuario actual desde la sesión. El parámetro user_id corresponde al valor devuelto por el método get_id() del usuario.

Configuración de mensajes personalizados

Flask-Login permite personalizar los mensajes de error y redirección que se muestran a los usuarios:

# Configurar mensajes personalizados
login_manager.login_message = 'Por favor, inicia sesión para continuar.'
login_manager.login_message_category = 'info'

# Configurar página para usuarios no autorizados
login_manager.needs_refresh_message = 'Tu sesión ha expirado, por favor inicia sesión nuevamente.'
login_manager.needs_refresh_message_category = 'warning'

La propiedad login_message_category define el tipo de mensaje que se mostrará en las plantillas, útil para aplicar diferentes estilos CSS según el contexto.

Configuración avanzada de sesiones

Para aplicaciones que requieren mayor control sobre las sesiones, podemos configurar opciones adicionales:

from datetime import timedelta

# Configurar duración de sesión
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=2)

# Configurar cookies de sesión
app.config['SESSION_COOKIE_SECURE'] = True  # Solo HTTPS en producción
app.config['SESSION_COOKIE_HTTPONLY'] = True  # Prevenir acceso desde JavaScript
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'  # Protección CSRF básica

Estas configuraciones mejoran la seguridad de las sesiones estableciendo límites de tiempo y restricciones en las cookies que almacenan la información de sesión.

Integración con la aplicación principal

Una vez configurados todos los componentes, la estructura básica de nuestra aplicación quedaría así:

from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required
from werkzeug.security import check_password_hash

app = Flask(__name__)
app.config['SECRET_KEY'] = 'tu-clave-secreta-muy-segura'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://usuario:password@localhost/mi_base_datos'

db = SQLAlchemy(app)

# Configuración Flask-Login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
login_manager.login_message = 'Debes iniciar sesión para acceder a esta página.'

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

# Modelo de usuario
class Usuario(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password_hash = db.Column(db.String(255), nullable=False)
    activo = db.Column(db.Boolean, default=True)

Esta configuración establece los fundamentos necesarios para que Flask-Login gestione automáticamente las sesiones de usuario, proporcionando una base sólida sobre la cual construir las funcionalidades de autenticación específicas de nuestra aplicación.

¿Te está gustando esta lección?

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

Sesiones de usuario

Una vez configurado Flask-Login, podemos implementar las operaciones fundamentales de gestión de sesiones: iniciar sesión, cerrar sesión y proteger rutas que requieren autenticación. Estas operaciones trabajan en conjunto para crear un sistema de autenticación completo y seguro.

Implementación del inicio de sesión

El proceso de inicio de sesión combina la validación de credenciales con la creación de una sesión activa. Flask-Login proporciona la función login_user() que establece automáticamente la sesión del usuario:

from flask import render_template, request, redirect, url_for, flash
from flask_login import login_user, current_user
from werkzeug.security import check_password_hash

@app.route('/login', methods=['GET', 'POST'])
def login():
    # Redirigir si ya está autenticado
    if current_user.is_authenticated:
        return redirect(url_for('dashboard'))
    
    if request.method == 'POST':
        email = request.form['email']
        password = request.form['password']
        remember = request.form.get('remember', False)
        
        # Buscar usuario en la base de datos
        usuario = Usuario.query.filter_by(email=email).first()
        
        # Verificar credenciales
        if usuario and check_password_hash(usuario.password_hash, password):
            login_user(usuario, remember=remember)
            flash('Inicio de sesión exitoso', 'success')
            
            # Redirigir a la página solicitada originalmente
            next_page = request.args.get('next')
            return redirect(next_page) if next_page else redirect(url_for('dashboard'))
        else:
            flash('Email o contraseña incorrectos', 'error')
    
    return render_template('login.html')

La función login_user() acepta un parámetro remember que determina si la sesión debe persistir después de cerrar el navegador. Cuando remember=True, Flask-Login crea una cookie permanente que mantiene la sesión activa durante el tiempo configurado en PERMANENT_SESSION_LIFETIME.

Acceso al usuario actual

Flask-Login proporciona el objeto current_user que permite acceder a la información del usuario autenticado desde cualquier parte de la aplicación:

from flask_login import current_user

@app.route('/perfil')
def perfil():
    if current_user.is_authenticated:
        return render_template('perfil.html', usuario=current_user)
    else:
        return redirect(url_for('login'))

El objeto current_user está disponible automáticamente en las plantillas Jinja, lo que permite mostrar información personalizada sin necesidad de pasarla explícitamente:

<!-- En la plantilla HTML -->
{% if current_user.is_authenticated %}
    <p>Bienvenido, {{ current_user.email }}</p>
    <a href="{{ url_for('logout') }}">Cerrar sesión</a>
{% else %}
    <a href="{{ url_for('login') }}">Iniciar sesión</a>
{% endif %}

Protección de rutas con decoradores

El decorador @login_required protege automáticamente las rutas que requieren autenticación. Cuando un usuario no autenticado intenta acceder a una ruta protegida, Flask-Login lo redirige automáticamente a la página de inicio de sesión:

from flask_login import login_required

@app.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html', usuario=current_user)

@app.route('/configuracion')
@login_required
def configuracion():
    return render_template('configuracion.html')

Si un usuario intenta acceder a /dashboard sin estar autenticado, Flask-Login lo redirigirá a /login?next=/dashboard, preservando la URL de destino para redirigir correctamente después del inicio de sesión exitoso.

Implementación del cierre de sesión

La función logout_user() elimina la información de sesión del usuario y limpia las cookies relacionadas:

from flask_login import logout_user

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('Has cerrado sesión correctamente', 'info')
    return redirect(url_for('login'))

El decorador @login_required en la ruta de logout asegura que solo usuarios autenticados puedan cerrar sesión, evitando errores innecesarios.

Gestión de sesiones con recordar usuario

Cuando un usuario selecciona la opción "Recordarme", Flask-Login gestiona automáticamente las cookies persistentes. Podemos personalizar este comportamiento:

from datetime import timedelta

@app.route('/login', methods=['POST'])
def login_post():
    # ... validación de credenciales ...
    
    if usuario and check_password_hash(usuario.password_hash, password):
        remember = request.form.get('remember', False)
        
        # Configurar duración personalizada para "recordar"
        if remember:
            login_user(usuario, remember=True, duration=timedelta(days=30))
        else:
            login_user(usuario, remember=False)
        
        return redirect(url_for('dashboard'))

Verificación del estado de sesión

Flask-Login proporciona varios métodos de verificación que podemos usar para controlar el acceso y personalizar la experiencia del usuario:

@app.route('/area_restringida')
def area_restringida():
    if not current_user.is_authenticated:
        flash('Debes iniciar sesión para acceder', 'warning')
        return redirect(url_for('login'))
    
    if not current_user.is_active:
        flash('Tu cuenta está desactivada', 'error')
        logout_user()
        return redirect(url_for('login'))
    
    return render_template('area_restringida.html')

Manejo de sesiones expiradas

Para aplicaciones que requieren renovación de sesión, podemos implementar verificaciones adicionales:

from datetime import datetime, timedelta

@app.before_request
def verificar_sesion():
    if current_user.is_authenticated:
        # Verificar si la sesión ha estado inactiva demasiado tiempo
        if 'last_activity' in session:
            if datetime.now() - session['last_activity'] > timedelta(hours=2):
                logout_user()
                flash('Tu sesión ha expirado por inactividad', 'warning')
                return redirect(url_for('login'))
        
        # Actualizar timestamp de última actividad
        session['last_activity'] = datetime.now()

Ejemplo completo de flujo de sesión

Un ejemplo práctico que integra todos los conceptos de gestión de sesiones:

@app.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('dashboard'))
    
    if request.method == 'POST':
        email = request.form.get('email')
        password = request.form.get('password')
        remember = bool(request.form.get('remember'))
        
        usuario = Usuario.query.filter_by(email=email).first()
        
        if usuario and usuario.activo and check_password_hash(usuario.password_hash, password):
            login_user(usuario, remember=remember)
            
            # Registrar último acceso
            usuario.ultimo_acceso = datetime.utcnow()
            db.session.commit()
            
            next_page = request.args.get('next')
            if next_page and is_safe_url(next_page):
                return redirect(next_page)
            return redirect(url_for('dashboard'))
        else:
            flash('Credenciales inválidas o cuenta desactivada', 'error')
    
    return render_template('login.html')

def is_safe_url(target):
    """Verificar que la URL de redirección es segura"""
    from urllib.parse import urlparse, urljoin
    ref_url = urlparse(request.host_url)
    test_url = urlparse(urljoin(request.host_url, target))
    return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc

Esta implementación completa maneja la autenticación segura, la persistencia de sesiones, la redirección apropiada y la validación de URLs para prevenir ataques de redirección maliciosa.

Aprendizajes de esta lección

  • Comprender la instalación y configuración básica de Flask-Login en una aplicación Flask.
  • Adaptar el modelo de usuario para integrarlo con Flask-Login mediante UserMixin.
  • Implementar funciones para iniciar sesión, cerrar sesión y proteger rutas con autenticación.
  • Gestionar sesiones persistentes y personalizar mensajes de autenticación.
  • Aplicar buenas prácticas de seguridad en la gestión de sesiones y validación de URLs de redirección.

Completa Flask y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración