JWT no es el villano de la historia. Tampoco es la respuesta automática para cualquier login, API o app con usuarios. El problema aparece cuando lo usas por costumbre, no por necesidad, y terminas cargando complejidad donde una sesión clásica o un token opaco te resolvían mejor la vida.
Si alguna vez tuviste que cerrar la sesión de un usuario de inmediato, invalidar accesos comprometidos o depurar un sistema con varios servicios, ya sabes de qué hablamos. JWT funciona bien en algunos escenarios, pero cuando la autenticación deja de ser un demo y pasa a ser operación real, sus ventajas se vuelven más pequeñas y sus costos más visibles.
El problema no es el formato, es la operación
JWT significa JSON Web Token. Es un formato firmado que te permite llevar claims dentro del token, como el subject, el issuer o la expiración. Eso suena limpio en papel, y muchas veces lo es. El detalle es que un token firmado no es lo mismo que un sistema de autenticación fácil de operar.
La provocación de “stop using JWTs” no apunta a borrar JWT del mapa. Apunta a cuestionar el impulso de usarlo como default. Si tu aplicación solo necesita saber si un usuario sigue autenticado, un JWT autoconclusivo puede ser más peso del necesario. Si además necesitas revocar, rotar, auditar y escalar sin dolores, el costo operativo sube rápido.
En sistemas modernos, la pregunta correcta no es “¿JWT o no JWT?” sino “¿qué problema resuelve aquí y cuál me agrega?”. En muchos equipos, JWT se adopta por tres razones: porque lo vio alguien en un tutorial, porque parece stateless, o porque “así se hace con microservicios”. Ninguna de esas razones te garantiza una buena decisión.
Qué te promete JWT y qué te cobra después
JWT te promete menos consultas a base de datos, validación local y menos acoplamiento entre servicios. Eso puede ser cierto si tu caso encaja. Pero te cobra con otra factura: revocación difícil, tokens más largos, manejo más delicado en el cliente y una falsa sensación de simplicidad.
Un ejemplo real: si emites un JWT de 24 horas y un usuario cambia su contraseña a los 10 minutos, ese token puede seguir vivo hasta que expire, salvo que montes una lista de revocación, cambies claves o introduzcas otra capa de control. Ya no estás en “solo firmar y listo”. Estás operando un sistema de invalidación.
También pasa con incidentes de seguridad. Si detectas que un refresh token fue filtrado, no basta con borrar una fila y ya. Debes pensar en rotación, familias de tokens, sesiones activas, caducidad, device binding y cómo vas a notificar o forzar logout. JWT no elimina ese trabajo. A veces lo desplaza.
Cuándo JWT sí complica de verdad
JWT empieza a estorbar cuando lo usas para resolver problemas que necesitan revocación inmediata o control fino de sesión. El caso típico es el de apps con usuarios reales, soporte real y riesgos reales. Ahí el “stateless” deja de ser una ventaja pura, porque el estado existe igual, solo que distribuido en tu infraestructura y en la cabeza de tu equipo.
Otra zona de fricción aparece cuando mezclas autenticación con autorización cambiante. Si el usuario cambia de rol, si un admin lo deshabilita, si una cuenta entra en revisión o si una política de acceso depende del contexto, un JWT con claims viejos puede quedarse desactualizado. Y mientras no expire, seguirá diciendo algo que ya no es cierto.
El problema se agrava en productos con soporte o compliance. Si tu equipo necesita responder preguntas como “¿cuándo se emitió este acceso?”, “¿desde qué dispositivo?”, “¿puedo apagar solo esta sesión?”, JWT puro no te resuelve eso por sí solo. Necesitas almacenamiento de sesiones, auditoría o un proveedor de identidad que maneje esos controles.
Revocación: el punto donde se rompe la magia
La revocación es el dolor más citado, y con razón. Un JWT válido no se puede invalidar mágicamente solo porque quieras; su firma sigue siendo válida hasta que expire o cambies la clave de firma. Eso significa que, si el token salió al mundo, su vida útil ya quedó en manos del reloj.
Hay formas de mitigarlo: expiraciones cortas, refresh tokens, listas de bloqueo, introspección, rotación de claves. Pero cada una agrega piezas. Si tu arquitectura ya tiene Redis, colas, varios servicios y una política de seguridad exigente, quizá puedas absorberlo. Si eres un equipo pequeño, cada pieza extra suma carga operativa.
En cambio, una sesión clásica con cookie httpOnly y almacenamiento server-side te deja invalidar una sesión en el acto. No es sexy, pero funciona. Para muchos productos SaaS, paneles internos y apps con login tradicional, esa simplicidad gana por goleada.
Claims desactualizados y autorización frágil
JWT suele usarse no solo para autenticar, sino para transportar roles, permisos o atributos del usuario. El problema es que esos datos quedan congelados al momento de emisión. Si guardaste role=editor y luego cambiaste al usuario a viewer, el token viejo puede seguir autorizando acciones que ya no debería.
Podrías acortar la expiración a 5 minutos. Podrías consultar el backend para validar permisos en cada request sensible. Podrías meter una versión de sesión en una base de datos. Pero en ese punto ya empezaste a desmontar el supuesto beneficio del JWT autoconclusivo.
La regla práctica es simple: cuanto más cambian tus permisos, menos sentido tiene meterlos dentro del token como verdad fija. Para datos estáticos y de bajo riesgo, puede servir. Para permisos que cambian seguido, mejor una fuente central de verdad.
Casos donde una sesión clásica gana
No necesitas JWT para todo. De hecho, hay varios escenarios donde una cookie de sesión clásica es más fácil de mantener, más segura en la práctica y más barata de operar. Esto aplica especialmente cuando tu aplicación vive en un solo dominio o en un conjunto pequeño de subdominios.
Si tu prioridad es cerrar sesiones rápido, invalidar accesos comprometidos y tener control centralizado, una sesión server-side suele ser mejor opción. También reduce la cantidad de lógica que el cliente debe entender. El navegador guarda una cookie; el servidor decide si sigue viva.
Eso no significa que JWT sea malo. Significa que, en ciertos contextos, te da menos valor del que promete. Si lo que necesitas es autenticación web tradicional, con expiración razonable y revocación clara, una sesión clásica te evita construir mecanismos que ya existían hace años.
| Escenario | JWT | Sesión clásica |
|---|---|---|
| Logout inmediato | Difícil sin capas extra | Directo |
| Permisos cambiantes | Riesgo de claims viejos | Más fácil de actualizar |
| APIs entre servicios | Útil si necesitas validación local | Depende de la arquitectura |
| Operación simple | Puede complicarse | Suele ser más simple |
| Auditoría por sesión | Requiere diseño adicional | Más natural |
Apps web tradicionales
Si estás construyendo un dashboard, un CRM, un backoffice o una app interna, una cookie httpOnly con sesión server-side suele ser suficiente. El navegador envía la cookie automáticamente, el servidor valida el identificador de sesión y tú conservas control total sobre expiración, revocación y rotación.
Además, en una app web tradicional, el argumento de “evitar estado” no siempre pesa tanto. Muchas veces ya tienes base de datos, caché y observabilidad. Agregar una tabla de sesiones no es un drama. En cambio, implementar correctamente JWT con refresh tokens, rotación y revocación puede ser más trabajo del que te ahorra.
Productos con soporte y compliance
Si trabajas con datos sensibles, cuentas empresariales o procesos de soporte donde necesitas apagar accesos rápido, JWT puro se queda corto. Un agente de soporte debe poder cerrar una sesión comprometida sin esperar a que el token expire. Un responsable de seguridad debe poder auditar accesos por dispositivo o IP.
Aquí la sesión clásica o un proveedor de identidad con controles finos suele encajar mejor. Lo importante no es el nombre de la tecnología, sino la capacidad de responder preguntas operativas sin inventar parches cada vez que aparece un incidente.
Cuándo JWT sí tiene sentido
JWT sigue teniendo lugar, y bastante. Sirve cuando necesitas transportar identidad o claims entre servicios, cuando la validación local reduce latencia o cuando integras sistemas donde no quieres depender de una consulta central por cada request. En esos casos, su formato firmado aporta valor real.
También puede ser útil en APIs públicas o en escenarios donde el token actúa como credencial de acceso de corta duración. Si lo emites con expiración breve y el sistema tolera esa ventana, JWT puede ser una pieza razonable. El punto no es prohibirlo, sino dejar de usarlo por reflejo.
La clave está en separar dos cosas: autenticación de usuario y transporte de credenciales entre componentes. Muchas arquitecturas mezclan ambas en el mismo token y luego se sorprenden cuando aparece la complejidad. Si el token solo necesita probar identidad por unos minutos, JWT puede encajar. Si además debe servir para revocar, auditar y controlar sesión, ya no es tan cómodo.
Microservicios y validación local
En microservicios, JWT puede ahorrar llamadas al auth server si cada servicio verifica la firma localmente. Eso reduce latencia y evita un cuello de botella central. Pero funciona mejor cuando las claims son estables y el riesgo de revocación inmediata no es crítico.
Si tu ecosistema tiene muchos servicios, el costo de distribuir claves, rotarlas y asegurar que todos respeten expiraciones coherentes no es trivial. No es imposible, pero tampoco es gratis. En organizaciones medianas, ese costo suele aparecer más tarde, cuando ya hay varios equipos dependiendo del mismo esquema.
Integración con proveedores de identidad
Si usas un IdP con OpenID Connect, muchas veces vas a recibir JWTs de todos modos. Eso no significa que debas diseñar tu propio sistema de sesión alrededor de ellos. Puedes aceptar tokens del proveedor y aun así mantener una estrategia clara de sesiones, expiración y control de acceso en tu app.
Para revisar especificaciones oficiales, puedes mirar la documentación de RFC 7519 para JWT y la guía de OpenID Connect Core. También vale la pena revisar cómo maneja cookies httpOnly la documentación de MDN. No necesitas memorizar todo, pero sí entender dónde termina el token y dónde empieza la sesión real.
Qué haríamos nosotros en un proyecto real
Si nosotros estuviéramos montando una app nueva, empezaríamos por la pregunta más aburrida y más útil: ¿necesitamos revocación inmediata? Si la respuesta es sí, JWT puro probablemente no sea la primera opción. Si la respuesta es no, todavía habría que revisar el ciclo de vida del token, el riesgo y la experiencia de soporte.
Después miraríamos el tipo de cliente. Para web tradicional, una cookie httpOnly con sesión server-side suele ser la ruta más simple. Para APIs entre servicios, podríamos usar JWT de corta duración solo como credencial de transporte. Para móviles o integraciones, revisaríamos refresh tokens, rotación y almacenamiento seguro antes de decidir.
También pondríamos atención a la operación. ¿Quién va a apagar una sesión comprometida? ¿Dónde se audita? ¿Qué pasa si cambias la clave de firma? ¿Cómo rotas sin tumbar a todos? Si esas preguntas no tienen respuesta clara, el diseño todavía no está listo.
Una decisión práctica en 5 pasos
- Define si necesitas logout inmediato. Si sí, evita depender solo de expiración.
- Clasifica tus permisos: si cambian seguido, no los congeles en un JWT largo.
- Decide dónde vive el estado de sesión: servidor, IdP o ambos.
- Limita la vida útil de cualquier credencial a lo mínimo razonable.
- Documenta revocación, rotación y auditoría antes de lanzar producción.
Señales de que JWT te está estorbando
- Necesitas invalidar accesos en segundos, no en horas.
- Tu equipo de soporte pide cerrar una sesión específica y no puede.
- Los roles cambian seguido y tus tokens quedan viejos.
- Ya montaste listas de bloqueo, refresh tokens y rotación, y aun así sigues resolviendo casos manuales.
- El beneficio de no consultar base de datos se perdió porque igual consultas varias cosas para compensar.
Si te reconoces en tres o más de esas señales, JWT probablemente dejó de ser una simplificación. Se volvió una capa más que mantener.
Tabla resumen
| Pregunta | Respuesta corta |
|---|---|
| ¿JWT siempre es mala idea? | No, pero no es el default para todo. |
| ¿Cuál es su mayor problema? | La revocación inmediata. |
| ¿Cuándo conviene una sesión clásica? | En apps web con logout y control central. |
| ¿Cuándo sí sirve JWT? | En credenciales cortas y validación local. |
| ¿Qué reviso antes de adoptarlo? | Expiración, revocación, auditoría y rotación. |
JWT no debería ser una postura ideológica. Debería ser una decisión técnica con costos claros. Si tu caso necesita sesiones revocables, soporte operativo y permisos que cambian seguido, probablemente te convenga menos que otras opciones. Si tu caso necesita transportar identidad de forma breve y verificable, entonces sí puede ser una buena herramienta.
La diferencia está en no confundir popularidad con conveniencia. En autenticación, la solución más elegante en el diagrama no siempre es la que mejor duerme en producción.
Preguntas frecuentes
¿JWT sirve para autenticación web tradicional?
¿Cuál es el principal problema de JWT?
¿Por qué dicen que JWT complica la operación?
¿JWT es malo para microservicios?
¿Qué alternativa usarías en una app interna?
¿Debo evitar JWT por completo?
¿Qué reviso antes de decidir?
Azirgo
¿Listo para construir tu Producto Digital?
Sitios web, apps móviles, software a medida y soluciones blockchain. Cuéntanos qué tienes en mente y armamos un plan claro contigo.
- Cotización clara en 48 horas
- Equipo en Ecuador, atención en español
- Desde un MVP hasta un producto en producción