Índice de contenido
- Qué es una sesión en Flask y para qué sirve
- Operaciones clave con Flask Session
- Consideraciones para apps móviles (Flutter / React Native)
- ⚠️ Nota sobre serialización de objetos en la sesión
- Diferencias entre sesión y cookies en Flask
- ⚙️ Configurar la sesión en un proyecto Flask
- Ejemplos prácticos de uso de session en Flask
- Mantener datos de usuario tras el login
- ️ Implementar un carrito de compras con Flask Session
- Extensión Flask-Session: sesiones del lado del servidor
- Instalación y configuración de Flask-Session
- Uso con Redis y otras opciones de almacenamiento
- Buenas prácticas y seguridad en Flask Session
- ️ Evitar exposición de datos sensibles
- ⏱️ Controlar la expiración de la sesión (session timeout)
- Configurar cookies seguras (SESSION_COOKIE_SECURE)
- Guardar arrays y múltiples elementos en la sesión de Flask
- Conclusión
- ❓ Preguntas frecuentes sobre Flask Session (FAQ)
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ón | Código |
|---|---|
| Leer dato | session.get('key') |
| Escribir / Guardar | session['key'] = 'valor' |
| Eliminar un dato | session.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
JWTen 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:
| Aspecto | Cookie | Session |
|---|---|---|
| Ubicación de los datos | Navegador del usuario (texto plano) | Servidor (o cifrados en cookie firmada) |
| Seguridad | Menor — el usuario puede leerla | Mayor — firmada criptográficamente |
| Duración | Según la fecha de expiración configurada | Caduca 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 sessionCon 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', 401La 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-Sessionfrom 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.idSin 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 sessionGuardar 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'] = roomsEl 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.
- Las sesiones basadas en cookies se mantienen mientras no cambie la
- ¿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.
- Usa
- ¿Es segura la sesión en Flask?
- Sí, siempre que uses una
secret_keyrobusta y aleatoria, activesSESSION_COOKIE_SECURE = Trueen producción (con HTTPS) y evites guardar datos sensibles directamente en la sesión.
- Sí, siempre que uses una
- ¿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 conbase64.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.
- La cookie de sesión está codificada en Base64 y firmada con la
- ¿Qué diferencia hay entre
session.pop()ysession.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.