Articles

¿qué es un Token Web JSON?

Posted by admin
Myplanet

Seguir

el 31 de Mayo de 2016 · 13 min leer

«Un JSON Web Token (JWT), que se pronuncia ‘jota’, es un compacto URL medios seguros de que representan créditos que se transfieren entre dos partes. Las notificaciones en un JWT se codifican como un objeto JSON que se firma digitalmente utilizando la firma web JSON (JWS)».,

Antes de entrar en JWTs, vamos a echar un vistazo rápido a cómo hemos utilizado para realizar la autenticación:

HTTP es un protocolo sin estado. Eso significa que no recuerda nada de una solicitud a otra. Si inicia sesión para una solicitud, se le olvidará, y tendrá que iniciar sesión de nuevo para hacer otra solicitud. Como se puede imaginar, esto puede ser muy molesto rápido.,

la solución de la vieja escuela ha sido crear lo que se llama una «sesión». Una sesión se implementa en dos partes:

  1. Un objeto almacenado en el servidor que recuerda si un usuario sigue conectado, una referencia a su perfil, etc.
  2. Una cookie en el lado del cliente que almacena algún tipo de ID que se puede referenciar en el servidor contra el ID del objeto de sesión.,

autenticación basada en cookies:

si un usuario visita una página web (hace una solicitud) y el servidor detecta una cookie de sesión, comprobará si actualmente tiene una sesión almacenada con el ID de la cookie, y si ese objeto sigue siendo válido (lo que signifique: no caducado, no revocado, no incluido en la lista negra, etc).

si la sesión sigue siendo válida, responderá con la página web solicitada (o datos)., Si encuentra un objeto de sesión, ese objeto puede contener datos en él y con eso, el servidor puede «recordar» quién es usted y qué estaba haciendo (por ejemplo, si se trata de una tienda de comercio electrónico, qué productos ha agregado a nuestro carrito de compras).

si la sesión no es válida (o no se detectó ninguna cookie de sesión) responderá con algún tipo de mensaje de error diciendo que la solicitud es «no autorizada».

normalmente se pueden crear nuevas sesiones enviando una combinación de nombre de usuario/contraseña a un punto final específico desde una página de inicio de sesión., Si el servidor puede hacer coincidir un usuario con ese nombre de usuario y contraseña, generará un nuevo objeto de sesión en el servidor y establecerá una cookie en el cliente con el ID de la sesión para cualquier solicitud futura.

si un usuario apaga su computadora y regresa al sitio web en algún momento en el futuro, puede iniciar sesión automáticamente de nuevo (si todavía hay una cookie en el navegador que no ha caducado) o iniciar sesión de nuevo a través de la página de inicio de sesión. Una vez iniciada la sesión, la sesión del Usuario se puede recuperar de nuevo de los datos almacenados en el servidor, y el usuario puede continuar con su negocio (p. ej., continuar comprando después de recargar su carrito de compras).

este tipo de configuración ha funcionado bastante bien para nosotros desde que salió la web y desde que hemos estado visitando sitios web que hacen la mayor parte de su «pensamiento» en el lado del servidor. Por lo general, esta ha sido una conversación entre el navegador front-end del usuario y un servidor back-end correspondiente en una relación uno a uno.,

esta configuración todavía funciona, pero en estos días tenemos muchas situaciones diferentes que requieren diferentes configuraciones (por ejemplo, múltiples aplicaciones nativas móviles junto con grandes aplicaciones web de una sola página que contactan múltiples servicios de backend, que pueden ser nada más que datos JSON sin una página web en absoluto)., En este tipo de escenarios, la cookie que se obtiene de un servidor, no corresponderá — o incluso se enviará — a otro servidor (por no hablar de los problemas que se crean con CORS).

  • Varios: Motores: ¿Qué pasa si tu aplicación necesita hablar con un servidor de base de datos así como una imagen separada de procesamiento de back-end?, Cada vez más, nuestro mundo digital se está dividiendo en microservicios separados; al autenticarse con más de un backend, las cosas pueden complicarse (por ejemplo, podría proxy todas las solicitudes a través de un servidor de Aplicaciones central que luego necesitaría conocer toda la lógica de cada servicio secundario, o cada servicio podría implementar comunicaciones complejas entre servidores (y CORS) para verificar los ID de sesión entrantes con un servidor de autenticación central… en cualquier caso, se requiere una carga adicional en el servidor de aplicaciones y se deben mantener interconexiones más complejas).,
  • sesiones: deben almacenarse en algún lugar, ya sea en memoria, en una base de datos o en un almacén de valores clave como Redis; y deben gestionarse para que se eliminen cuando caduquen o se invaliden de otro modo.
  • escalabilidad deficiente: el almacén de sesiones debe escalarse al escalar el servidor. La tienda consume recursos y añade complejidad.
  • Problemas de rendimiento: cuando la sesión necesita ser almacenada en el servidor, una gran cantidad de búsquedas de bases de datos/almacenes deben ocurrir en cada solicitud que puede atascar el servidor.,
  • aplicaciones nativas (o aplicaciones que no son del navegador): los navegadores manejan las cookies, pero las aplicaciones personalizadas no lo hacen (al menos no fácilmente), por lo que se necesita un tipo diferente de mecanismo de sesión.
  • CSRF: si se utilizan cookies, se necesita una seguridad adicional para evitar ataques cross-site request forergy, ya que la cookie se enviará automáticamente al servidor con cualquier solicitud realizada desde ese sitio.
  • CORS: las Cookies + CORS no funcionan bien en diferentes dominios (en realidad, los dominios cruzados reales no funcionan en absoluto).,

los Tokens Web JSON son mejores

Los JWT no usan sesiones, no tienen problemas con las aplicaciones nativas y, en realidad, ni siquiera necesitan protecciones CSRF especiales, y funcionan como un encanto con CORS.

Con JWT usted se registre, con una aplicación, de la misma manera que lo haría con un viejo-aplicación de la escuela, y que el inicio de sesión con sus credenciales (por ejemplo, nombre de usuario/contraseña, o la 3ª parte de OAuth)., Pero en lugar de hacer una sesión y establecer una cookie, el servidor le enviará un Token Web JSON en su lugar. Ahora puede usar ese token para hacer lo que quiera hacer con el servidor (para lo que tiene autorización).

piénsalo como una llave de hotel: te registras en la recepción y te dan una de esas llaves electrónicas de plástico con las que puedes acceder a tu habitación, a la piscina y al garaje, pero no puedes abrir las habitaciones de otras personas ni entrar en la oficina del gerente. Y, al igual que una llave de hotel, cuando su estancia ha terminado, simplemente se queda con un pedazo inútil de plástico (I. e., el token ya no hace nada después de que ha expirado).

En un multi-servidor configurado, también se podría imaginar una JWT similar a la de un «Festival Pass» como la que se obtendría en una película o un festival de música., Mientras que una entrada de cine individual le otorgará acceso a una sola película de la que puede salir para obtener palomitas de maíz o usar el baño y regresar, un pase de Festival le otorgará acceso a cualquier película en todo el festival en diferentes lugares y en diferentes momentos. De la misma manera, puede tomar su JWT generado desde un servidor y usarlo para autenticarse con servidores totalmente diferentes en diferentes dominios, que comparten el mismo método de verificación., Cada uno de esos otros servidores no necesita «llamar a casa» para preguntar si el token está bien, porque simplemente pueden hacer un cálculo rápido en el token en sí y verificar su firma y tiempo de caducidad directamente sin incurrir en una visita a la base de datos o una solicitud de red adicional.

cómo funciona JWT

un JWT es autónomo. Cuando crea uno, tiene todas las piezas necesarias que necesita para hacer las cosas que desea hacer en un servidor empaquetado dentro de él. Hay 3 partes principales, separadas por una «.,»:

  1. Un encabezado
  2. Una carga útil
  3. Una firma

el encabezado normalmente contiene dos cosas: el tipo del token (cómo se puede interpretar la carga útil), y el nombre del algoritmo utilizado para hacer la firma (por ejemplo, {typ: ‘JWT’, alg: ‘hs256’}). Esto se codifica en base64.

la firma es un hash del encabezado codificado, la carga codificada y una clave «secreta» que usted proporciona (almacenada de forma segura en el servidor) utilizando el algoritmo definido en el encabezado.

al final, se obtiene una cadena que se ve algo así como » xxxxxxxx.yyyyy.,zzzzzzzz «donde» x «es la cabecera codificada,» y «es la carga codificada, y» z » es la firma cifrada.

el encabezado y la carga útil se pueden decodificar fácilmente en el front-end o el back-end para recuperar cualquier información que desee allí (es solo base64). Tenga esto en cuenta porque estos valores son esencialmente «públicos», así que no ponga ninguna información privada allí como un número de tarjeta de crédito o una contraseña o algo así.

cada vez que realiza una solicitud al servidor, envía el token con su solicitud. Normalmente esto se hace en el encabezado de autorización como » Authorization: Bearer xxxxxx.,yyyyy.zzzzzz». Pero también podría pasarse en un cuerpo de POST o en la propia URL como un parámetro de consulta. Cuando el servidor ve el token, lo decodifica y compara la firma con el secreto que ha almacenado que se habría utilizado para generar el token en primer lugar. Si todo coincide, la solicitud es auténtica y responde con datos; de lo contrario, devuelve un mensaje de error.

Aquí hay un ejemplo de token real. Usted puede utilizar este buen servicio jwt.io para inspeccionar fácilmente el token si desea ver lo que hay dentro de él.,

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vZXhhbXBsZS5v
cmciLCJhdWQiOiJodHRwOi8vZXhhbXBsZS5jb20iLCJpYXQiOjEzNTY5OTk1MjQsIm5iZ
iI6MTM1NzAwMDAwMCwiZXhwIjoxNDA3MDE5NjI5LCJqdGkiOiJpZDEyMzQ1NiIsInR5cC
I6Imh0dHBzOi8vZXhhbXBsZS5jb20vcmVnaXN0ZXIiLCJjdXN0b20tcHJvcGVydHkiOiJ
mb28iLCJuYW1lIjoiUm9iIE1jTGFydHkiLCJpZCI6Nzh9.-3BnaA1XRiKh8e7zy9ZRTET
f8VngoypqrVW98oQnH4w

el servidor toma información de la carga útil del token (por ejemplo, como un «userId») y construye su respuesta en consecuencia. Así es como el servidor «recuerda» al usuario, porque puede usar el ID que encuentra para verificar el nombre del usuario y otra información de perfil contra su cuenta en la base de datos (o simplemente puede usar los datos que hay en la carga útil directamente sin golpear la base de datos en absoluto). Si se han otorgado derechos de acceso especiales al usuario, también se pueden recuperar desde el token (por ejemplo, privilegios de administrador).,

la clave (juego de palabras) para todo esto es la cadena «secreta» que se almacena en el servidor. Esta es una pieza de información que solo el servidor sabe que se utiliza para hacer nuevos tokens y validar los existentes. Debido a que el servidor es lo único que conoce el secreto, evita el acceso no autorizado de los atacantes porque sería técnicamente demasiado difícil descifrar una firma capturada, o adivinar el secreto para falsificar una firma artificial antes de que caduque un token emitido. Recuerde nunca compartir su secreto con nadie y enviarlo a su servidor a través de una línea segura (p. ej., usando SSH).

también puede configurar otros servidores para que usen el mismo secreto de modo que un token creado por un servidor también pueda usarse para autenticarse con un servidor completamente diferente (cliente a servidor o servidor a servidor)., También se pueden crear configuraciones más avanzadas usando Jwa (algoritmos Web JSON) donde un servidor de autenticación Central almacena un solo secreto y los servidores de terceros reciben una clave pública generada a partir de ese secreto y usan la Clave Pública para solicitar servicios de autenticación del servidor de autenticación cuando el servidor de terceros recibe una solicitud (basta con decir que hay muchas formas diferentes de configurar las cosas; es muy flexible).

si un atacante intenta manipular los datos de la carga (p. ej., para darse derechos de administrador), la firma correspondiente no coincidirá (porque la firma se generó a partir de los datos originales en la carga útil) y, como tal, ese token no se considerará válido en el servidor y cualquier solicitud realizada con él será denegada. La única manera de crear un token auténtico es con el secreto (que solo debe estar en el servidor y nunca publicado).

un JWT también puede incluir otra información útil en su carga útil, llamada «reclamaciones». Lo más importante es una fecha de caducidad., Si se incluye una fecha de caducidad, el token se invalidará automáticamente cuando haya pasado esa fecha.

reclamaciones JWT estándar

hay un conjunto de propiedades estándar que puede usar en su carga útil para manejar diferentes casos de uso en su aplicación. Reclamaciones como esta se pueden utilizar para aumentar la seguridad de su sistema para evitar una serie de diferentes tipos de ataques. Asegúrese de comprobar lo que está disponible en la biblioteca que elija.,

  • iss: el emisor del token
  • sub: el sujeto del token
  • aud: la audiencia del token
  • exp: esta será probablemente la reclamación registrada más utilizada. Esto definirá la caducidad como un valor NumericDate. El vencimiento debe ser después de la fecha/hora actual.
  • nbf: define la hora antes de la cual el JWT no debe ser aceptado para el procesamiento
  • iat: la hora en que se emitió el JWT. Se puede utilizar para determinar la edad de la JWT
  • jti: identificador único para la JWT. Se puede utilizar para evitar que el JWT se reproduzca., Esto es útil para un token de uso único.

Ejemplo payload:

cómo invalidar un JWT

la parte más interesante de un JWT es que sus notificaciones pueden incluir su configuración de caducidad y debido a que la firma es una función del hash de estas configuraciones, todo lo que el servidor necesita hacer es verificar la información de Caducidad cuando verifica el token y rechazarlo si ha expirado. Lo que esto significa es que no tienes que preocuparte demasiado por ello. Después de emitir un token, simplemente déjalo en la naturaleza y déjalo morir por sí solo.

obviamente no todas las aplicaciones pueden permitirse hacer esto., A veces tener un token válido a la vista incluso durante un día es potencialmente demasiado largo (por ejemplo, tal vez para otorgar a un usuario acceso a su cuenta si olvidó su contraseña). A veces es posible que solo desee que un token se use una sola vez (por ejemplo, para restablecer la contraseña). Otras veces es posible que tenga un usuario malicioso registrado en su sistema al que desea prohibir por completo para que los tokens que ya han creado ya no se puedan usar para acceder al sistema.

estos escenarios se pueden manejar (si es necesario) a través de una combinación de reclamaciones JWT y mecanismos del lado del servidor., Tenga en cuenta las siguientes opciones al considerar la invalidación y caducidad del token:

  • eliminar el token del cliente
  • mantener una lista negra de tokens
  • Mantener los tiempos de caducidad cortos

la primera opción simplemente «arroja» el token y lo deja caducar por sí solo.

la segunda opción está un poco más involucrada en que rastrea los tokens reales almacenados en el servidor (por ejemplo, en una base de datos o almacén de claves/valores) y usa esta lista durante la verificación de tokens para verificar si un token ha sido incluido en la lista negra., Esto es una especie de lo contrario de las tiendas de sesión, pero aún es más eficiente porque como los tokens caducan naturalmente, simplemente se pueden eliminar de la lista negra. La lista negra solo es necesaria para invalidar un token que aún no ha caducado.,

finalmente, en general, debe mantener los tiempos de caducidad de su token cortos de todos modos (como menos de 24 horas; tal vez solo 1 o 2 horas) para que en el peor de los casos, un atacante tenga menos de un día para aprovechar, lo que probablemente no sea suficiente tiempo para forzar brutalmente el cifrado de la firma, incluso con un superordenador the El jurado todavía está en las computadoras cuánticas.

ventajas de JWTs

  • No hay sesión que administrar( sin estado): el token tiene todo lo que necesita para identificar a los usuarios, y el resto del Estado de su aplicación se puede almacenar en el almacenamiento local en el lado del cliente., No hay necesidad de un objeto de sesión almacenado en el servidor.
  • Portable / Homogenous: un único token se puede utilizar con múltiples backends, incluso en diferentes dominios.
  • No se requieren Cookies: puede almacenar el token como queramos: en localStorage, indexDB o en alguna tienda nativa (o cookies, si realmente lo desea).
  • Mobile Friendly: desarrollar aplicaciones nativas (iOS, Android, Windows 8, etc.) es difícil y engorroso con las cookies (tienes que lidiar con contenedores de cookies), pero adoptar un enfoque basado en tokens simplifica enormemente esto.,
  • Caducidad incorporada: JWT tiene notificaciones estándar que se pueden establecer en la carga útil cuando se crea un nuevo token. No hay nada más que hacer.
  • no es necesario cerrar sesión: simplemente deseche el token cuando haya terminado con él, caducará por sí solo. Por lo general, desea dar un tiempo de caducidad corto, pero si realmente lo desea, puede realizar un seguimiento de una «lista negra» de tokens que están marcados como «inválidos» en el servidor que podría agregarse desde un cierre de sesión explícito, o desde un administrador que marque ciertos tokens como inválidos.,
  • funciona con CORS: un enfoque de autenticación basado en tokens le permite hacer llamadas AJAX a cualquier servidor, en cualquier dominio porque puede usar un encabezado HTTP para transmitir la información del usuario.
  • aproveche las CDN: puede servir todos los activos para su aplicación desde una CDN (por ejemplo, javascript, HTML, imágenes, etc.) y su lado del servidor puede ser simplemente una API sin estado.
  • Fácil de depurar: los JWT pueden ser inspeccionados y sus datos revisados (mientras que las sesiones se almacenan en el servidor y son mucho más difíciles de ver y entender).
  • desacoplado / descentralizado: el token se puede generar en cualquier lugar., La autenticación puede ocurrir en el servidor de recursos, o separarse fácilmente en su propio servidor, o» auto-emitido», o de otra manera ser completamente externalizado.
  • CSRF no importa: porque si no tienes un token, no puedes hacer nada. Dado que no necesita confiar en las cookies, no necesita protegerse contra las solicitudes de sitios cruzados (p. ej., no sería posible<iframe> generar una solicitud POST y reutilizar la cookie de autenticación existente porque no habrá ninguna) ya que el JWT debe incluirse explícitamente en el encabezado de la solicitud, y no se configura automáticamente como una cookie.
  • buen rendimiento: es probable que un viaje de ida y vuelta a la red (por ejemplo, encontrar una sesión en la base de datos, deserializarla y luego extraer la información que le interesa) lleve más tiempo que calcular un HMACSHA256 para validar un token y analizar su contenido.,
  • basado en estándares: lea las especificaciones: RFC 7519 compatible con múltiples bibliotecas backend (. NET, Ruby, Java, Python, PHP, Javascript) y empresas que respaldan su infraestructura (por ejemplo, Firebase, Google, Microsoft, Zendesk).

Eso es todo! ¡Ve y libérate de tus opresores de galletas! Y luego déjanos un comentario para hacernos saber lo bien que se siente esa libertad y compartir la liberación con tus amigos enviando este artículo a su manera.

Escrito por: Rob McLarty

Este artículo fue publicado originalmente en http://robmclarty.com/blog

Leave A Comment