Sesión en Flask: Guía Completa con Redis y Ejemplos

- Andrés Cruz - EN In english

Video thumbnail

Cuando desarrollamos una aplicación web con Flask, llega un momento inevitable: necesitamos mantener información del usuario entre peticiones. Ya sea saber quién inició sesión, qué hay en su carrito de compras o qué preferencias configuró. Esto va mucho más allá de los mensajes flash en Flask, que solo persisten durante una única petición.

Ahí es donde entra en juego la sesión en Flask: una herramienta ligera y muy práctica para gestionar datos temporales del usuario, ya sea del lado del servidor o del cliente, según la configuración que elijas.

En esencia, la sesión sirve para almacenar información relacionada con un usuario concreto a lo largo de su navegación. Datos como su nombre, su identificador único o sus preferencias pueden vivir en la sesión sin necesidad de consultarlos en cada petición. La usaremos ampliamente en capítulos posteriores, especialmente en el flujo de autenticación.

Un caso de uso clásico, y quizás el más habitual, es el del carrito de compras: cada producto que el usuario agrega se registra en la sesión hasta que finaliza la compra o cierra el navegador.

Algo importante a tener en cuenta: los datos de la sesión son temporales. La sesión tiene una fecha de caducidad configurada o implícita, y eventualmente expirará.

Además, la sesión se va modificando de forma dinámica a lo largo del ciclo de vida del usuario: se crea cuando inicia sesión, se actualiza cuando cambia algún dato y se destruye al cerrar sesión o finalizar una compra.

Qué es una sesión en Flask y para qué sirve

Una sesión es un espacio de almacenamiento temporal que guarda información entre distintas solicitudes HTTP. En Flask, cada usuario tiene su propia sesión, identificada mediante una cookie segura firmada con una clave secreta.

Por ejemplo, cuando un usuario inicia sesión correctamente, su nombre o ID se guardan en la sesión para reconocerlo en cada visita posterior. En mi caso, suelo usarla exactamente para eso: almacenar los datos del usuario autenticado sin tener que pedirlos de nuevo en cada página ni hacer una consulta extra a la base de datos.

Para utilizar la sesión es necesario establecer una clave secreta (secret_key), que Flask usa para firmar criptográficamente el contenido de la cookie. Esto garantiza que el cliente no pueda manipular los datos de la sesión. Esta clave debe estar definida desde el inicio del proyecto, ya sea directamente en el archivo principal o en tu archivo de configuración personalizado en Flask:

app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

Operaciones clave con Flask Session

Para gestionar tus sesiones de manera eficiente, estas son las operaciones más comunes que usarás en tus rutas y controladores:

AcciónCódigo
Leer datosession.get('key')
Escribir / Guardarsession['key'] = 'valor'
Eliminar un datosession.pop('key', None)
Limpiar sesión completa (Logout)session.clear()

Consideraciones para apps móviles (Flutter / React Native)

Si estás consumiendo tu API Flask desde una aplicación móvil como Flutter o React Native, recuerda que aunque las apps nativas no suelen tener las mismas restricciones de CORS que un navegador web, al probar en emuladores o webviews integrados, el manejo de cookies y sesiones puede comportarse de forma distinta.

Buenas prácticas para sesiones en mobile:

  • No confíes ciegamente en cookies: Algunas plataformas móviles gestionan las cookies de forma volátil o directamente no las persisten entre sesiones. Para apps móviles, considera usar tokens JWT en lugar de sesiones basadas en cookies.
  • Configura correctamente el preflight: Si tu app móvil envía encabezados personalizados, asegúrate de que tu configuración de Flask-CORS permita las solicitudes OPTIONS.
  • HTTPS obligatorio con cookies seguras: Si utilizas SESSION_COOKIE_SECURE = True, tu API debe servirse bajo HTTPS; de lo contrario, la cookie de sesión no se enviará y la sesión no se mantendrá en dispositivos móviles.

⚠️ Nota sobre serialización de objetos en la sesión

¡Cuidado! Nunca intentes guardar objetos complejos —como instancias de SQLAlchemy o modelos de base de datos— directamente en la sesión.

Flask serializa el contenido de la sesión a formato JSON para guardarlo en la cookie. Si intentas almacenar un objeto que no es serializable, obtendrás un error del tipo "Object of type X is not JSON serializable". La regla es simple: guarda solo datos primitivos (strings, números, listas, diccionarios) o estructuras que puedas convertir a JSON manualmente.

Diferencias entre sesión y cookies en Flask

Aunque ambas permiten guardar información entre peticiones HTTP, existen diferencias clave que determinan cuándo usar una u otra:

AspectoCookieSession
Ubicación de los datosNavegador del usuario (texto plano)Servidor (o cifrados en cookie firmada)
SeguridadMenor — el usuario puede leerlaMayor — firmada criptográficamente
DuraciónSegún la fecha de expiración configuradaCaduca automáticamente o al llamar session.clear()

⚙️ Configurar la sesión en un proyecto Flask

Antes de usar la sesión, necesitas configurar la secret_key que Flask utiliza para firmar las cookies y evitar manipulaciones. Sin ella, Flask lanzará un error al intentar acceder al objeto session.

Puedes definirla directamente en tu archivo principal:

from flask import Flask
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

Para usar la sesión en cualquier ruta, importa el objeto session desde Flask:

from flask import session

Con eso disponible, puedes guardar datos en la sesión exactamente igual que en un diccionario de Python:

session['username'] = 'user'

Recuperar un valor es igual de directo:

session['username']

Y para eliminar un dato puntual sin destruir toda la sesión, usa session.pop():

session.pop('username', None)

El segundo argumento None evita que se lance un KeyError si la clave no existe, lo que hace que este patrón sea seguro incluso si el usuario ya había cerrado sesión previamente.

Ejemplos prácticos de uso de session en Flask

Para verlo todo junto, aquí tienes un módulo de prueba con tres rutas que cubren el ciclo completo de una sesión: crearla, consultarla y eliminarla:

from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'clave_super_secreta'

@app.route('/test/session/set')
def test_session_set():
   session['username'] = 'user'
   return 'Sesión creada para user'

@app.route('/test/session/check')
def test_session_check():
   if 'username' in session:
       return f'Usuario autenticado: {session["username"]}'
   return 'No hay sesión activa'

@app.route('/test/session/pop')
def test_session_pop():
   session.pop('username', None)
   return 'Sesión eliminada'

Prueba las tres rutas en orden: primero /test/session/set para crear la sesión, luego /test/session/check para verificarla y, finalmente, /test/session/pop para eliminarla. Esto te da una idea clara del ciclo de vida de una sesión en Flask.

Mantener datos de usuario tras el login

Cuando un usuario inicia sesión correctamente, basta con asignar sus datos al objeto session. Esto permite identificarlo en cualquier parte de la aplicación durante toda su sesión activa, sin necesidad de consultar la base de datos en cada petición.

@app.route('/login', methods=['POST'])
def login():
    user = User.query.filter_by(email=request.form['email']).first()
    if user and user.check_password(request.form['password']):
        session['user_id'] = user.id
        session['username'] = user.name
        return redirect(url_for('dashboard'))
    return 'Credenciales incorrectas', 401

La recomendación habitual —y la que yo sigo— es guardar solo el user_id en la sesión y hacer una consulta a la base de datos cuando necesites los datos completos del usuario. Así reduces el tamaño de la cookie y los datos siempre estarán actualizados.

️ Implementar un carrito de compras con Flask Session

En otro proyecto, utilicé la sesión para guardar una lista de productos de forma sencilla:

session['cart'] = ['Libro A', 'Libro B']

Y al finalizar la compra, bastaba con limpiar ese dato de la sesión:

session.pop('cart', None)

Para un carrito más complejo (con cantidades, precios, variantes, etc.), puedes guardar una lista de diccionarios. Recuerda siempre reasignar la variable en la sesión después de modificarla, ya que Flask no detecta cambios internos en objetos mutables de forma automática (ver la sección de arrays más abajo).

Extensión Flask-Session: sesiones del lado del servidor

Por defecto, Flask guarda toda la sesión en una cookie firmada del cliente. Esto funciona bien en aplicaciones pequeñas, pero tiene un límite: las cookies tienen un tamaño máximo de 4 KB. Si necesitas almacenar más datos o quieres que la sesión persista en el servidor con mayor control, la extensión Flask-Session es la solución.

Instalación y configuración de Flask-Session

$ pip install Flask-Session
from flask_session import Session

app.config['SESSION_TYPE'] = 'filesystem'
Session(app)

Con SESSION_TYPE = 'filesystem', los datos de sesión se guardan en archivos en el servidor en lugar de en la cookie del cliente. Esto te permite almacenar objetos más grandes y tener mayor control sobre la expiración.

Uso con Redis y otras opciones de almacenamiento

Para aplicaciones distribuidas o de mayor escala, puedes usar SESSION_TYPE = 'redis' y apuntar a un servidor Redis:

import redis

app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.from_url('redis://localhost:6379')
Session(app)

Redis es ideal cuando tienes múltiples instancias de tu aplicación corriendo en paralelo, ya que todas comparten el mismo almacén de sesiones. Otras opciones disponibles en Flask-Session son sqlalchemy, mongodb y memcached.

Buenas prácticas y seguridad en Flask Session

️ Evitar exposición de datos sensibles

Nunca guardes contraseñas, tokens de acceso o información privada directamente en la sesión. Utiliza identificadores anónimos (como el user_id) y, si necesitas proteger datos adicionales, aplica cifrado antes de almacenarlos.

⏱️ Controlar la expiración de la sesión (session timeout)

Puedes configurar el tiempo de vida de la sesión usando permanent_session_lifetime junto con session.permanent = True:

from datetime import timedelta

app.permanent_session_lifetime = timedelta(minutes=30)

@app.route('/login')
def login():
    session.permanent = True
    session['user_id'] = user.id

Sin session.permanent = True, la sesión expira al cerrar el navegador (sesión de navegador). Con esa línea activa, Flask respeta el valor de permanent_session_lifetime y la sesión dura el tiempo configurado aunque el usuario cierre y reabra el navegador.

Configurar cookies seguras (SESSION_COOKIE_SECURE)

En producción, marca siempre la cookie de sesión como segura para que solo se transmita por HTTPS:

app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'

SESSION_COOKIE_HTTPONLY = True impide que JavaScript del lado del cliente acceda a la cookie, lo que protege contra ataques XSS. SESSION_COOKIE_SAMESITE = 'Lax' reduce el riesgo de ataques CSRF en la mayoría de los escenarios.

Guardar arrays y múltiples elementos en la sesión de Flask

La sesión en Flask no está limitada a strings o números: puedes almacenar listas, diccionarios o cualquier estructura de datos que sea serializable a JSON. Esto abre la puerta a casos de uso más complejos, como mantener una lista de elementos activos por usuario sin necesidad de base de datos.

Flask proporciona el objeto session, que se comporta como un diccionario de Python normal. Puedes importarlo directamente desde el framework:

from flask import session

Guardar múltiples valores en la sesión es tan directo como esto:

session['age'] = 30
session['name'] = "Andres"

Ahora bien, hay un detalle importante al trabajar con listas dentro de la sesión: Flask no detecta cambios internos en objetos mutables de forma automática. Si modificas una lista o un diccionario que ya está en la sesión, debes reasignarlo explícitamente para que Flask lo marque como modificado y actualice la cookie. El patrón correcto es este:

def addRoomSession(room):
    if 'rooms' not in session:
        session['rooms'] = []

    rooms = session['rooms']    # 1. Obtenemos la lista de la sesión
    rooms.append(room)          # 2. Modificamos la lista local
    session['rooms'] = rooms    # 3. La reasignamos para que Flask detecte el cambio
    print(session['rooms'])

def removeRoomSession(room):
    if 'rooms' not in session:
        return

    rooms = session['rooms']
    rooms.remove(room)
    session['rooms'] = rooms

El truco está en la reasignación del paso 3. Sin ella, Flask podría no guardar los cambios en la cookie porque el objeto en memoria es el mismo y la cookie no se marca como modificada. Una alternativa es activar session.modified = True manualmente tras cualquier mutación interna, aunque la reasignación explícita es más clara y portable.

Este código forma parte de mi curso completo sobre Flask, donde vemos cómo trabajar con Flask-SocketIO y el concepto de habitaciones (rooms), un caso de uso real donde la sesión juega un papel clave.

Conclusión

La sesión en Flask es una herramienta esencial para mantener datos del usuario entre peticiones sin complicar el backend. Su combinación de simplicidad y seguridad la hace perfecta para gestionar el login, carritos de compras o cualquier flujo que requiera persistencia temporal.

Si tu proyecto crece y la cookie de 4 KB se queda pequeña, puedes ampliar la capacidad con Flask-Session respaldado por Redis, garantizando escalabilidad y control total sobre los datos de sesión.

❓ Preguntas frecuentes sobre Flask Session (FAQ)

  • ¿Qué pasa si el servidor se reinicia?
    • Las sesiones basadas en cookies se mantienen mientras no cambie la secret_key. Las sesiones del lado del servidor (filesystem, Redis) pueden perderse si no usas almacenamiento persistente o si el proceso se reinicia sin persistencia configurada.
  • ¿Puedo guardar objetos complejos en la sesión?
    • Sí, pero deben ser serializables a JSON (listas, diccionarios, strings, números). Los objetos de SQLAlchemy o instancias de clases personalizadas no son serializables directamente.
  • ¿Cómo elimino todos los datos de sesión a la vez?
    • Usa session.clear() para limpiar la sesión por completo. Es la forma más común de implementar el logout en Flask.
  • ¿Es segura la sesión en Flask?
    • Sí, siempre que uses una secret_key robusta y aleatoria, actives SESSION_COOKIE_SECURE = True en producción (con HTTPS) y evites guardar datos sensibles directamente en la sesión.
  • ¿Cómo decodifico una cookie de sesión de Flask?
    • La cookie de sesión está codificada en Base64 y firmada con la secret_key, pero no cifrada. Puedes ver su contenido decodificando la parte antes del primer punto con base64.b64decode(), pero no podrás falsificarla sin conocer la clave secreta. Por eso es crítico que esa clave sea compleja y no quede expuesta en repositorios públicos.
  • ¿Qué diferencia hay entre session.pop() y session.clear()?
    • session.pop('key', None) elimina únicamente el dato con esa clave, dejando el resto de la sesión intacta. session.clear() destruye toda la sesión de golpe, útil para implementar el logout completo.

Recomendación: Guarda únicamente el identificador (user_id) del usuario en la sesión y, en cada petición, consulta tu base de datos para obtener el resto de los detalles. Así los datos siempre están actualizados y la cookie se mantiene pequeña.

El siguiente paso: aprende a usar formularios en Flask con WTForms.

Aprende a gestionar sesiones en Flask paso a paso: cómo guardar, leer y limpiar datos con session.clear(), controlar el timeout y usar Flask-Session con Redis.


Únete a la comunidad de desarrolladores que han decidido dejar de picar código y empezar a construir productos reales. Recibe mis mejores trucos de arquitectura cada semana:

Acepto recibir anuncios de interes sobre este Blog.