Autenticación: uso de JWT frente a sesión

122

¿Cuál es la ventaja de usar JWT sobre sesiones en situaciones como la autenticación?

¿Se utiliza como enfoque independiente o se utiliza en la sesión?

Pourya8366
fuente

Respuestas:

212

JWT no tiene ningún beneficio sobre el uso de "sesiones" por decir. Los JWT proporcionan un medio para mantener el estado de la sesión en el cliente en lugar de hacerlo en el servidor.

Lo que la gente suele decir cuando pregunta esto es "¿Cuáles son los beneficios de usar JWT en comparación con las sesiones del lado del servidor? "

Con las sesiones del lado del servidor, tendrá que almacenar el identificador de la sesión en una base de datos, o bien mantenerlo en la memoria y asegurarse de que el cliente siempre llegue al mismo servidor. Ambos tienen inconvenientes. En el caso de la base de datos (u otro almacenamiento centralizado), esto se convierte en un cuello de botella y algo que mantener, esencialmente una consulta adicional que se debe realizar con cada solicitud.

Con una solución en memoria, limita su escalamiento horizontal y las sesiones se verán afectadas por problemas de red (clientes en itinerancia entre Wifi y datos móviles, reinicio de servidores, etc.)

Mover la sesión al cliente significa que elimina la dependencia en una sesión del lado del servidor, pero impone su propio conjunto de desafíos.

  • Almacenar el token de forma segura
  • transportarlo de forma segura
  • Las sesiones de JWT a veces pueden ser difíciles de invalidar.
  • Confiando en el reclamo del cliente.

Estos problemas los comparten los JWT y otros mecanismos de sesión del lado del cliente por igual.

JWT, en particular, aborda el último de estos. Puede ser útil comprender qué es un JWT:

Es un poco de información. Para las sesiones de usuario, puede incluir el nombre de usuario y la hora en que caduca el token. Pero posiblemente podría ser cualquier cosa, incluso el ID de sesión o el perfil completo del usuario. (No obstante, no hagas eso) Tiene una firma segura que evita que las partes malintencionadas generen tokens falsos (necesitas acceso a la clave privada del servidor para firmarlos y puedes verificar que no se modificaron después de firmarlos). envíelos con cada solicitud, al igual Authorizationque se enviaría una cookie o un encabezado. De hecho, se envían comúnmente en el Authorizationencabezado HTTP, pero usar una cookie también está bien.

El token está firmado y el servidor puede verificar su origen. Asumiremos que el servidor confía en su propia capacidad para firmar de forma segura (debe usar una biblioteca estándar: no intente hacerlo usted mismo y asegure el servidor correctamente)

Sobre el tema del transporte seguro del token, la respuesta suele ser enviarlo a través de un canal cifrado, generalmente httpS.

Con respecto al almacenamiento seguro del token en el cliente, debe asegurarse de que los malos no puedan acceder a él. Esto (principalmente) significa evitar que JS de sitios web defectuosos lean el token para enviárselo. Esto se mitiga utilizando las mismas estrategias que se utilizan para mitigar otros tipos de ataques XSS.

Si tiene la necesidad de invalidar JWT, definitivamente hay formas de lograrlo. Almacenar una época por usuario solo para los usuarios que han solicitado que sus "otras sesiones terminen" es un método muy eficiente que probablemente será lo suficientemente bueno. Si una aplicación necesita invalidación por sesión, entonces se puede mantener un ID de sesión de la misma manera y la tabla de "tokens eliminados" aún se puede mantener para que sea mucho más pequeña que la tabla de usuario completa (solo necesita retener registros más nuevos que el la vida útil del token más larga permitida). Por lo tanto, la capacidad de invalidar el token niega parcialmente el beneficio de las sesiones del lado del cliente en el sentido de que tendría que mantener este estado de sesión cancelada. Es más que probable que sea una tabla mucho más pequeña que la tabla de estado de sesión original, por lo que las búsquedas son aún más eficientes.

Otro beneficio de usar tokens JWT es que es razonablemente fácil de implementar usando bibliotecas disponibles en probablemente todos los idiomas que puede esperar tener. También está completamente divorciado de su esquema de autenticación de usuario inicial: si se cambia a un sistema basado en huellas digitales, no necesita realizar ningún cambio en el esquema de administración de sesiones.

Un beneficio más sutil: debido a que el JWT puede transportar "información" y el cliente puede acceder a ella, ahora puede comenzar a hacer algunas cosas inteligentes. Por ejemplo, recuérdele al usuario que su sesión expirará unos días antes de que cierre la sesión, dándole la opción de volver a autenticarse, según la fecha de expiración del token. Todo lo que puedas imaginar.

En resumen: los JWT responden a algunas de las preguntas y deficiencias de otras técnicas de sesión.

  1. Autenticación "más barata" porque puede eliminar un viaje de ida y vuelta a la base de datos (¡o al menos tener una tabla mucho más pequeña para consultar!), Lo que a su vez permite la escalabilidad horizontal.
  2. Reclamaciones del lado del cliente a prueba de manipulaciones.

Si bien los JWT no responden a otros problemas como el almacenamiento o el transporte seguros, no presentan ningún problema de seguridad nuevo.

Existe mucha negatividad en torno a los JWT, pero si implementa la misma seguridad que usaría para otros tipos de autenticación, estará bien.

Una nota final: tampoco es Cookies vs Tokens. Las cookies son un mecanismo para almacenar y transportar bits de información y también se pueden utilizar para almacenar y transportar tokens JWT.

El Tahaan
fuente
4
Vale la pena señalar que las sesiones del lado del servidor tampoco tienen que almacenar ninguna información en el servidor. El servidor puede usar el cliente como tienda de la misma manera que lo hace JWT. La verdadera diferencia está en 1) evitar las reglas de seguridad del navegador pasando el valor como encabezado de solicitud que no sea un encabezado de cookie, y 2) tener un formato estandarizado con JWT.
Xeoncross
1
¿Diría que es seguro almacenar un jwt en un almacenamiento local? Si no es así, ¿dónde hay un lugar seguro para guardarlo para que el usuario permanezca conectado?
Jessica
1
Sí, el almacenamiento local es generalmente el lugar más correcto para almacenarlo del lado del cliente. Necesita lidiar con XSS - No soy un experto en programación web, pero mire esta respuesta stackoverflow.com/a/40376819/1810447 y busque "Cómo protegerse contra XSS"
The Tahaan
1
En su comentario no habla de solución basada en caché + token de sesión. Me suena "mejor" que la tabla JWT + "fichas muertas", porque con esta tabla de "fichas muertas", de todos modos necesita un acceso a la base de datos, que también tendrá con sesiones + caché (que también es pequeña). Y persistir JWT es más doloroso de implementar que persistir sesiones, porque necesitas jugar con un refresh_token (por lo tanto, dos tokens para mantener) ... Cualquier comentario sería muy apreciado ... especialmente si tienes algún número para mostrar cómo JWT + kill_table es más eficiente que las sesiones + caché ;-)
tobiasBora
2
No se recomienda @TheTahaan localStorage para almacenar JWT. El enlace que compartiste también lo menciona. Este blog tiene una buena explicación de por qué JWT no debe almacenarse en localStorage.
Harke
40

La respuesta corta es: ninguna.

Una versión más larga es:

Implementé JWT para la gestión de sesiones después de leer esta recomendación en los documentos de GraphQL :

Si no está familiarizado con ninguno de estos mecanismos de autenticación, le recomendamos que utilice express-jwt porque es sencillo sin sacrificar ninguna flexibilidad futura.

La implementación fue realmente simple, ya que solo agregó un poco de complejidad. Sin embargo, después de un tiempo, (como usted) comencé a preguntarme cuáles eran los beneficios. Resulta que hay muy pocos (o posiblemente ninguno) para JWT en lo que respecta a la gestión de sesiones, como explica en detalle esta publicación de blog:

Deja de usar JWT para las sesiones

Carl von Blixen
fuente
0

Mis dos centavos, que en el camino añaden algo de contraste a la famosa publicación de blog de joepie91.

Teniendo en cuenta que las aplicaciones de hoy (y de mañana) son (en su mayoría) nativas de la nube , la autenticación JWT sin estado
tiene un beneficio económico , que se escala a medida que la aplicación se escala: las aplicaciones en la nube incurren en costos junto con cada respiración que se extrae . Este costo se reduce cuando los usuarios ya no tienen que autenticarse "contra" un almacén de sesiones.

Procesamiento
Ejecutar una tienda de sesión 24 horas al día, 7 días a la semana cuesta dinero.
No puede salirse con la suya con soluciones basadas en memoria en el mundo de K8S, ya que los pods son efímeros.
A las sesiones pegajosas no les irá bien exactamente por la misma razón.

Almacenamiento El
almacenamiento de datos cuesta dinero. almacenar datos en un SSD cuesta aún más.
Las operaciones relacionadas con la sesión deben resolverse rápidamente, por lo que una unidad óptica no es una opción.

E / S
Algunos proveedores de la nube cobran dinero por las E / S relacionadas con el disco.

Ancho de banda
Algunos proveedores de nube cobran por la actividad de la red entre instancias de servidor.
Esto se aplica ya que es casi seguro que la API y el almacén de sesiones son instancias separadas.

Agrupación de la tienda de sesiones
El costo aumenta aún más todos los costos mencionados anteriormente.

Eyal Perry
fuente
"No puede salirse con la suya con soluciones basadas en memoria en el mundo de K8S, ya que los pods son efímeros" No estoy seguro de lo que quiere decir con esto. Redis definitivamente funciona en un entorno K8S, y parece muy poco probable que un pod de redis falle con la frecuencia suficiente para afectar a sus usuarios.
quietContest
@quietContest Personalmente prefiero no lidiar con la probabilidad al crear software. Por cierto, dejando de lado la estabilidad de la solución, un ataque puede hacer que el software falle y que los pods se reinicien, lo que provocaría la pérdida de la sesión. Optaría por una solución basada en JWT por esa razón.
Eyal Perry
1
"Personalmente prefiero no lidiar con la probabilidad cuando construyo software". Creo que todos preferiríamos eso, razón por la cual no deberíamos diseñar sistemas que dependan de almacenes de datos en memoria que nunca fallen, porque la probabilidad de que eso ocurra parece razonablemente alta. En cuanto a su otro punto, si tiene un atacante que puede cerrar constantemente su instancia de redis, la solución probablemente no necesite involucrar el uso de JWT.
quietContest
@quietContest consistentemente o un evento único en la vida son lo mismo para mí en este aspecto. es decir, un ataque DDoS bien ubicado puede hacer que el servidor "cierre la sesión de los usuarios". Esto no funciona bien para la reputación de confiabilidad del software. Creo que Redis es excesivo para la gestión de sesiones de todos modos. Cuesta y debe escalarse, mientras que almacenar (de forma segura) un JWT en una cookie no lo hace.
Eyal Perry
1
@quietContest gracias por tu aporte, ¡me encanta la discusión!
Eyal Perry