- JWT es la sigla de JSON Web Tokens y es un estándar para tokens autenticados.
- JWT se compone de un encabezado, una carga útil y una firma o código de autenticación de mensajes.
- Cualquiera que tenga la clave de verificación puede confirmar la autenticidad de la carga útil.
Patrones de uso comunes de JWT
- JWT incluye información como emisor, destinatario, sujeto y fecha de expiración.
- El destinatario verifica la autenticidad del token, luego comprueba que no haya expirado y considera al sujeto como un usuario autenticado.
Ventajas de JWT
- La principal ventaja de JWT es que el destinatario puede verificar la autenticidad del token sin conectarse a la base de datos de usuarios.
- En entornos de despliegue a gran escala, el servicio de autenticación puede ser el único servicio con acceso a la base de datos central de usuarios.
Problemas con el cierre de sesión y la invalidación de sesiones
- Los tokens de autenticación deben tener una vida útil corta. Por ejemplo, como máximo 5 minutos.
- El cliente también recibe un token de refresco con el que puede solicitar nuevos tokens de autenticación.
- El token de refresco termina cumpliendo el papel del verdadero token de sesión.
Casos en los que JWT no es necesario
- Para implementar el cierre de sesión, hay que mantener una lista de permisos de JWT válidos o una lista de bloqueo de JWT revocados.
- Para bloquear a un usuario, hay que verificar en la base de datos un indicador de "usuario activo".
- Se necesitan relaciones adicionales entre el objeto de usuario y otros objetos.
- Se realizan operaciones relacionadas con la base de datos.
Conclusión
- Si se cumple хотя бы una de las condiciones anteriores, no necesitas JWT.
- Es mejor usar un token de sesión opaco convencional y almacenarlo en la base de datos.
- Así puedes evitar las desventajas de JWT y reducir la complejidad.
Opinión de GN⁺
- JWT es adecuado para servicios a gran escala, pero para la mayoría de los servicios pequeños puede introducir una complejidad excesiva.
- Los mecanismos convencionales de gestión de sesiones son suficientes para la mayoría de las aplicaciones web.
- Usar JWT puede dificultar la implementación de funciones como el cierre de sesión y la invalidación de sesiones.
- Para aprovechar las ventajas de JWT, hay que considerar cuidadosamente la escala del servicio y sus requisitos.
- Como alternativa, también se pueden considerar frameworks de autenticación como OAuth2.
8 comentarios
Hubo muchas ventajas al usar JWT cuando se necesitaba autenticación para diversos clientes.
Sin embargo, como la escalabilidad y la seguridad siempre apuntan en direcciones distintas, si la seguridad es especialmente importante, creo que es mejor usar otro método.
Personalmente, creo que los tokens JWT conviene usarlos cuando se intercambian entre sistemas, a través del navegador, datos temporales para los que no importa si se exponen.
Para los tokens de autenticación que contienen información personal, me parece mejor usar tokens
opaque.Por mi experiencia personal, JWT sí tenía ventajas cuando se trataba de construir un MVP.
Por ejemplo, si era un servicio que una sola persona creaba y mantenía, la idea era reducir el costo de planificación ante solicitudes repentinas. Como las relaciones de datos que se definieron al inicio terminaban cambiando por completo uno o dos meses después, cuando la planificación aún no estaba clara, al menos en lo relacionado con
auth, recuerdo que era mejor diseñar el payload de JWT con campos opcionales e implementar así las features. De ese modo, aunque el equipo de planificación no trabajara en la separación de dominios y servicios, al menos se podía implementar en un servicio monolítico de forma que solo el dominio pudiera separarse fácilmente, y luego probar el mercado. (Y después seguir el proceso de separar el servicio. O eliminarlo.)Aun así, creo que depende del dominio del servicio que se quiera construir. Ese proyecto, incluso dentro de los servicios en tiempo real, tenía una integración muy fuerte con terceros... así que recuerdo que avanzamos con esa idea pensando que, si implementábamos rápido, podrían acumularse cantidades enormes de documentos/rows en la base de datos y eso haría crecer el costo de mantenimiento.
Claro, si el foco es construir rápido, me parece mejor el enfoque con sesiones. (Al principio, como el acoplamiento entre varios servicios todavía no es tan fuerte, también es más fácil rehacer todo y volver a construirlo). Además, el costo de transferencia de conocimiento cuando se suma otro miembro del equipo también es menor.
En ese momento sí lo pensé bastante por un rato, pero la verdad, viéndolo ahora en retrospectiva, creo que el impacto en el proyecto no habría sido tan serio sin importar cuál de las dos opciones hubiéramos implementado.
Personalmente, creo que al usar un API gateway se obtienen beneficios cuando la autenticación se implementa con JWT, pero me gustaría saber qué ventajas tiene JWT en servicios de pequeña escala. ¿Te refieres a casos en los que la información del usuario incluida en el JWT cambia con frecuencia?
En líneas generales, es parecido a lo que mencionaste. Solo que, más que cambiar seguido el modelado del usuario en sí para modificar información con frecuencia, se parecía más a casos donde se agregaba información de forma opcional cuando una nueva feature o un nuevo servicio que requería usar herramientas de terceros pedía información adicional. (Y, si entro un poco más en detalle, estábamos en una situación algo ambigua sobre si separar la unidad de gestión de
authpotencialmente usando algo como un API gateway, o si habría un servidor que cumpliera un rol equivalente...)Para dar un ejemplo un poco más concreto, estábamos en una situación donde el servicio principal era A. Como todavía era un MVP, en la tabla de usuarios solo teníamos información de pago y si el usuario estaba autenticado. Pero llegó una solicitud para agregar los servicios B y C, que solo podían usarse si cada usuario tenía información de autenticación distinta. Entre ellos, ni siquiera estaba decidido si B iba a integrarse dentro del servicio A, y como C incluso podía desaparecer, querían probarlo de forma ligera. (Y la funcionalidad de gestión de planes, aunque nadie lo dijera, era de esas cosas que más valía agregar de una vez para evitar problemas). Además de eso, querían empezar probando B y C junto con la página web desde la que ya se ofrecía el servicio A. Por las características del servicio en operación, hasta no crear una tabla de gestión de planes (o una tabla genérica relacionada con autenticación) y mapear las relaciones de dominio por servicio para implementarlo, era inevitable consultar varias tablas (o varias colecciones). En una situación donde hubiera alguien que pudiera ordenar el proyecto, habría sido ideal tener algunas reuniones y definir con precisión cuál era exactamente el problema a resolver y qué features se querían. Pero no era un contexto donde eso estuviera garantizado. Además, tampoco estaba claro cuándo se podrían saldar esas deudas técnicas. Así que era una situación en la que algo así podía pasar, y de hecho ya se veían señales desde antes del lanzamiento del servicio A... Al pensar en la primera arquitectura, concluimos que en
authconvenía ir por una forma que ahorrara lo más posible en costo de consultas y en costo de mantenimiento futuro, y por eso lo hicimos con JWT. Además de eso, creo que hubo muchísimos otros casos pequeños de naturaleza similar.Pero, como mencioné al final del comentario, en realidad creo que, sin importar con qué se hubiera implementado, no habría tenido un impacto tan grande en el proyecto en sí. Si lo hubiéramos hecho con sesiones, probablemente habríamos encontrado una forma de resolverlo a nuestra manera. Más bien, creo que fue mucho más grave estar expuestos constantemente a situaciones donde los desarrolladores tenían que hacerse cargo de trabajo de otras áreas o donde el costo de comunicación terminaba rompiéndose.
Aunque sea adecuado para una arquitectura monolítica, cuando se separan algunos servicios o se llega a un punto de expansión, JWT y la lógica basada en sesiones muestran diferencias claras. Más que un simple procedimiento de autenticación, también cambian las técnicas para manejar la fuente de los datos en términos de usabilidad dentro de la lógica interna, y no tengo claro con qué criterio debería juzgarse que el contexto de un servicio pequeño es el adecuado. No sé si se parte de la premisa de que todos los servicios necesariamente serán pequeños, o de que los servicios grandes no serán fáciles de manejar. Aun así, creo que los servicios que construimos deberían contar, al menos de forma mínima, con una estructura que respalde contextos útiles aunque no sepamos en qué situación se necesitarán. La premisa de un servicio pequeño parece que solo lleva a que siga siendo pequeño.
Opiniones de Hacker News
Resumen de comentarios de Hacker News