Autenticación en Flask - Cómo mejoré login y registro para hacerlo más seguro - Episodio 30

Menudo lío la autentificación en Flask.
Pensé que con devolver un token ya tenía resuelto el login.
Hasta que un día, sin esperarlo, vi cómo cualquiera podía registrarse dos veces... con el mismo email.
🔥 Parecía que mi sistema de login funcionaba... hasta que descubrí fallos críticos que podían comprometer toda la API. Diario de un SaaS
Al principio, tener un login funcional me parecía suficiente.
Claro está, si entrabas con usuario y contraseña y te devolvía un token, estaba hecho.
Pero como suele pasar en el desarrollo de un SaaS... lo que parece "funcionar" puede esconder peligros invisibles.
Aunque preparando la cena me vino a la cabeza que no estaba del todo bien... porque:
- No había validación real de contraseñas.
- Podías registrar el mismo email varias veces si escribías alguna letra distinta.
- No tenía trazabilidad de los intentos de acceso.
Y entonces lo vi claro: mi sistema de autenticación no protegía a nadie.
Solo aparentaba hacerlo.
Y ya sé... daba el pego...
Pero no!

🛠️ Las mejoras que implementé
✅ Validación avanzada de contraseñas
Ya no vale cualquier password. Ahora las contraseñas deben tener:
- Mínimo 8 caracteres.
- Al menos 1 mayúscula.
- Al menos 1 minúscula.
- Al menos 1 número.
- Al menos 1 símbolo especial.
Esto lo gestiono desde el schema de Marshmallow:
import re
from marshmallow import ValidationError
def strong_password(value):
if not re.match(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$', value):
raise ValidationError("La contraseña no cumple con los requisitos de seguridad")
✅ Prevenir duplicación de usuarios
Antes, si registrabas el mismo email con una letra diferente en mayúscula o minúscula, colaba. Ahora, normalizo el email y verifico si ya existe:
email = data['email'].strip().lower()
existing_user = User.query.filter_by(email=email).first()
✅ Logs detallados de login
Cada intento de login ahora se registra:
- Si el usuario existe.
- Si la contraseña es incorrecta.
- Si el login fue exitoso.
if not user:
app.logger.info(f"Login fallido - Usuario no encontrado: {data['email']}")
elif not check_password(data['password']):
app.logger.warning(f"Login fallido - Contraseña incorrecta para: {user.email}")
else:
app.logger.info(f"Login exitoso: {user.email}")
💡 Lecciones aprendidas
🔹 No basta con que el login funcione
Una autenticación "que parece funcionar" puede ser un espejismo peligroso si no protege activamente a los usuarios.
🔹 La seguridad está en los detalles
Validar bien una contraseña, registrar cada intento, evitar duplicidades... todo suma.
🔹 Siempre hay algo que se te escapa
Revisar tu propio código como si fueras un atacante es una práctica que debería ser obligatoria.
🧠 Reflexión personal
Este proceso me enseñó algo más allá del código: no todo error viene con un bug visible.
A veces, lo más peligroso es lo que parece estar bien.
Y esa sensación de seguridad falsa es quizás el mayor enemigo en cualquier sistema.
Implementar estas mejoras me hizo consciente de lo fácil que es caer en la complacencia cuando el sistema “responde como esperas”.
Pero el verdadero desafío está en anticiparte a lo que podría ir mal.
Y eso no se enseña en un tutorial.
Cuidar la autenticación no fue solo una mejora técnica, fue también una forma de asumir responsabilidad real sobre los datos de otros.
Y eso cambia la forma en que ves tu propio trabajo.
🚂 Próximo paso: Afinar la conexión con PostgreSQL y optimizar consultas
Ahora que la autenticación está bajo control, toca mejorar la conexión con la base de datos y asegurarnos de que todo fluya sin cuellos de botella.
💭 ¿Alguna vez creíste que tu sistema era seguro y luego descubriste que no tanto?
Cuéntamelo en los comentarios. 🚀
Si quieres conocer otros artículos parecidos a Autenticación en Flask - Cómo mejoré login y registro para hacerlo más seguro - Episodio 30 puedes visitar la categoría Proyecto-IA.

Deja una respuesta