El concepto de JSON Web Token es cada día más común en el desarrollo de aplicaciones web .¿Qué es un JSON Web Token y como funciona?. Un JSON Web Token es un contenedor de información referente a la autenticación de un usuario.
Vamos a verlo un poco más a detalle.
¿Cual es la estructura de este contenedor?
Un JSON Web Token esta dividido en tres partes .
- La primera es la que se denomina JOSE o JavaScript Object Signing and Encryption y define cual es la tecnología criptográfica que se va a aplicar al token para securizar la información.
- La segunda parte es lo que se denomina JWT PayLoad o JWT Claims y almacena la información de negocio que necesitamos en el token. Esta parte se puede estructurar de muchas formas.
- La tercera parte es la firma JWT que se encarga de dar validez al token.
Cada una de las partes esta codificada en Base64 y separadas por un punto.
Esto está muy bien pero es difícil de entender como funciona. Vamos a intentar clarificar los conceptos usando un ejemplo de un token con sus partes.
JSON y JOSE (I)
Empezaremos por la parte JOSE:
{ "alg": "HS256", "typ": "JWT" }
Aquí vemos como definimos el tipo de token y el algoritmo criptográfico que vamos a utilizar (HS256). ¿Esto que quiere decir exactamente? . En nuestro caso quiere decir que estamos usando un token JWT ( el más común) y un algoritmo de HASH muy concreto denominado HMAC que genera un hash con SHA256 utilizando una clave privada. Si no hemos entendido la frase no hay que preocuparse, es normal, más adelante lo explicaremos . Veamos la segunda parte del token.
JSON Web Token y Claims
Este bloque define la información que vamos a almacenar de negocio . En nuestro caso únicamente almacenaremos el nombre del usuario:
{ "nombre": "Cecilio" }
JSON y Firma
La tercera parte del token simplemente es un hash con la siguiente estructura:
HMAC(base64UrlEncode(jose)+”.” +base64UrlEncode(claims),clave)
Criptografia y JSON Web Token
Para entender JWT necesitamos repasar algunos de conceptos criptográficos . Lo primero que tenemos que entender es el concepto de algoritmo de HASH. Un algoritmo de HASH se encarga de generar un HASH (bloque de caracteres de longitud fila) a partir de una cadena arbitraria de texto.
Los algoritmos de hash sirven para comprobar que en ningún momento se ha modificado el texto original ya que se aseguran de que ante dos textos distintos siempre se genera un hash diferente. Por lo tanto si alguien nos cambia el texto original y lo intenta dar por valido podemos regenerar el hash y comprobar si cumple.
JSON Web Token y HMAC
¿Qué es lo que tiene en especial usar un algoritmo HMAC para generar el hash?. Lo que tiene de especial es que este algoritmo criptográfico se encarga de generar un hash para un texto utilizando una clave privada.
Esto implica una diferencia importante ya que los HASH solo los pueden generar aquellas personas que conozcan la clave privada. Por lo tanto no solo sabemos ahora que el contenido no ha sido modificado sino también podemos saber quien es su creador. Vamos a profundizar un poco mas con este diagrama:
El diagrama explica como se genera el HASH
- En primer lugar generamos las estructuras de base64 tanto de la parte JOSE como de los Claims
- En segundo lugar usaremos el algoritmo HMAC con su clave privada para generar un HASH basado en las estructuras de Base64.
Realizadas ambas operaciones el último paso es sumarlo todo y generar un token:
Este token será el que enviemos al cliente y le permitirá autenticarse más adelante.
JWT y Servidor
La forma de procesar los tokens JWT esta ligada al servidor pero básicamente es algo del estilo:
- El cliente se logea en el servidor y envía usuario y clave
- El sistema le valida y genera un token usando el algoritmo HMAC y la clave privada
- El cliente recibe el token
- El cliente solicita unos datos y pasa como identificador el token
- El servidor decodifica los bloques de base64 y usa su clave privada para comprobar el HASH .Si todo es correcto permite el acceso y envía la información solicitada al cliente.
Estos son los conceptos fundamentales detrás de JWT. A continuación se muestra un ejemplo de Token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJub21icmUiOiJjZWNpbGlvIn0.MCfaorSC7Wdc8rSW7BJi9xuJb7G8RQzasfzsm_y-COI
Podemos ver los puntos que separan cada parte del token y si queremos podemos decodificar los dos primeros bloques.En el siguiente artículo veremos como construir una implementación sencilla de JWT.
Otros artículos relacionados
Una pregunta. En una arquitectura de microservicios, como funciona los token JWT. Supongamos que el cliente se autentica con un servidor externo, supongamos Facebook. Este le devuelve un token JWT. Luego el cliente hace una petición de un recurso a un microservicio y le pasa el token JWT en el Authentication Header.
Como sabe el microservicio que el token JWT es válido. Se supone que no tiene la clave privada que utilizó Facebook. Entonces, como hace dicho microservicio para saber si es válido?
eso tiene que ver mas con oauth
Ok, gracias por tu respuesta Cecilio y por la información del artículo, excelente. Aprovecho para preguntarte otra vez sobre el comentario de arriba, porque no me quedó claro. Básicamente, la pregunta del microservicio de ejemplo que consulto en la pregunta de arriba, es porque no me queda claro como hace un servicio para validar que el token JWT enviado por un cliente es válido o no. Con otros tokens, como los Bearer Tokens creo que es necesario que el servicio se comunique con el servidor de autenticación para saber si es válido o no. Con JWT también sería necesaria dicha… Read more »
si necesitaria tener la clave , no queda otra
Hola, el json web Token, sería el famoso token en la tecnología blockchain. Cómo lo relaciono con la cadena de bloques ? El token se almacena en la base de datos como un registro? Como una transacción del bloque ? Me podrías aclarar cómo se guarda el token en la cadena ? Tengo un token que representa la operación de compra venta o la adquisición de un producto , está cadena de caracteres encriptada dónde se guarda ? En una tabla de que tipo ?
no tengo ni idea no estoy metido
Estimado Cecilio Podria realizar una diferencia en tre OAUT2 VS JWT a su estilo que es lo personal es único soy de Lima Perú y realmente es sorprendente lo otro queria preguntarle si tendra al curso de bd tipo oracle
Me apunto lo de oaut vs jwt y del curso de base de datos es genérico los diagramas estan hechos con una herramienta que exporta tanto a mySQL como a Oracle. Eso si esta grabado con mySQL 🙂
Se que estoy equivocado pero me gustaria saber porque
Pienso que no es necesario encriptar la clave privada con hash porque de todos modos yo podria tener una cadena normal en mi servidor y podria ponerla en el token y cuando el token regrese al comparar la clave del token con mi clave de todos modos podria averiguar las diferencias y saber si cambio con una simple comparacion
Podria ayudarme con eso?
la clave privada no se encripta y no se envia 🙂
Muy Buen Articulo despejo las dudas que tenia sobre los JWT gracias
de nada 🙂
Muchas gracias !
de nada 🙂
Excelente articulo, no se imagina de la utilidad que fue. Muchisimas gracias por compartirlo.
de nada 🙂
Profesor tendrá algún curso donde se haga una aplicacion utilizando JWT y Spring, cordial saludo
Probablemente lo publicaré en algún curso 🙂
Securizar o asegurar?
esta claro que es mejor asegurar 🙂 , pero a veces uno se desvía hacia el ingles 🙂
Excelente artículo, tengo una duda, estoy implementando una interfaz de exámenes en linea con JSF, primefaces, wildfly y quisiera saber si el uso de JWT sería optimo para este requerimiento, ya que mi idea es que en cada pregunta al seleccionar la respuesta se realice la petición POST al servidor, valide el token y realice los cambios en la base de la respuesta seleccionada, pero el tema aquí es que la cantidad de usuarios que estarían rindiendo el examen al tiempo sería entre 3000 hasta 8000 mas o menos.
Cualquier sugerencia es bienvenida muchas gracias.
En principio si es primefaces sobre angular si que tiene sentido ,sino no tanto es mejor usar autentificación clasica del servidor
Muchas gracias por compartir esta publicación. Estoy comenzando con validaciones y me ha sido de mucha utilidad.
Un saludo.
de nada 🙂
Buenas, muchas gracias por la explicación, Necesito poder anular un token por que se genera con mucho tiempo de vida útil, me gustaría saber como implementar la lista negra para la anulación.
Se suele añadir al token una caducidad
Buenas, se podría dar el caso en que te parasen una peticion get o post obtener el token del Authorization y utilizarlo para lanzar todas consultas a nuestra API?
Un saludo
el token tiene que tener un tiempo de caducidad , eso esta claro y hay que refrescarlo cada poco 🙂
Hola, me gusto mucho tu artículo, yo quisiera implementarlo en distintos servidores me explico quisiera loguearme en un sitio y con el token auto loguearme en otro sitio en un servidor distinto. Podría hacerlo?
En otro sitio sí si usas algo tipo single sign on , en otro servidor ya sería más dificil
Gran explicación, y aprovecho para consultarte algo, puede que sea algo obvio pero soy nuevo en esto.
Lo que hace JWT es bloquear todo menos lo que tu digas a menos que tenga el token, la pregunta es como puedo evitar que gente con token valido pueda entrar a lugares donde no debe según su perfil de la empresa por ejemplo.
Deberías añadir mas informacion al token como por ejemplo el role
Hola… ante todo muy bueno tu articulo. He leído otros artículos y me queda una duda, no se si sea un poco tonta pero…, en el servidor después que haya comparado la cadena recibida (token) y verificada… , ¿como hago para comparar si los datos desencriptados son los reales?? Tengo que extraer datos de mi BD y luego comparar??? Leí en otro lado que este mecanismo es mucho mas eficiente porque no hace uso de la BD.
Muchas Gracias..
En principio con acceder a los datos del token y generar la estructura de signatura con tu clave y comprobar que coincide es suficiente
Muy buen articulo Cecilio, esta muy claro.
Quedamos a la espera de la implementacion de JWT (espero que sea en Java 😉 jee )
Saludos !
gracias 🙂
Buenas,
No termino de entender el funcionamiento.
Sí yo hago login se me envia un token con el cual puedo realizar las peticiones http que lo requieran.
Pero mi duda es cada vez que te logueas te da un token?. Si es así que seguridad tiene si yo consigo el user y la pass de un usuario me dará un token y podré hacer todo.
Sí por ejemplo hago login con el PC y me da un user y luego con el móvil que me da dos token?
Un saludo y gracias
Podras añadir al token información de tiempo de vida para que por ejemplo solo dure 30 minutos
Manuel, si alguien roba el user y la pass, ¿Cómo esperas que el sistema pueda saber si eres el usuario o el ladrón?
normalmente se asigna un tiempo de timeout
Justo esa duda tenía (Manuel y Daniel), pienso que utilizar un tipo de auténticacion basic por ejemplo al servicio de validación de la cuenta de usuario que genera el token, al menos agregaria un punto para que no cualquiera pueda consumir el servicio, ya después sólo usas en webtoken para los métodos que se requieran utilizar y por el tiempo de validez configurado.
:/.
un ejemplo para entender….. gracias
de nada , me alegro que te fuera útil
Muy buen el post!!
Una duda, las partes JOSE y Claims ¿no se cifran con la clave privada? ademas de, base 64. Si he entendido bien hay autenticidad pero no hay confidencialidad de los datos.
claro que hay confidencialidad de datos , ya que generamos un hash no se puede desencriptar ,los datos están protegidos. Lo único que podemos hacer en el servidor es volver a generar el hash a partir del usuario
Hola, No se si no entendí bien pero me salta una duda, si el token que se genera en el login alguien lo roba y lo utiliza al mismo tiempo en el que el usuario esta logeado, entonces podría hacer peticiones al servidor como si fuera el usuario real. Es esto posible o como es que se evita.
Se les suele asignar un tiempo de caducidad en la parte de claims para que no tengan una validez muy amplia. Pero tienes razón en lo que dices . Por eso hay que intentar guardalo bien 🙂
Muy buen artículo y de vital importancia a la hora de desarrollar apps que tienen casi toda la carga en los JS del cliente y en las que no tenemos “tan a mano” el poder preguntar por sesiones activas en servidor. ¿A la hora de hacer peticiones nuevas que requieran estar logueados es necesario enviar el token como parte de la petición? Por ejemplo una petición ajax que envia un JSON (por post, put, delete…) y devuelve otro JSON con el resultado de lo que ha hecho el backend. ¿Ahí necesitaríamos adjuntar el token a la petición para que el… Read more »
Bueno almacenar los datos de la sessión en un local storage puede ser razonable . Es cierto que se pueden leer pero no es información crítica. No puedes almacenar los datos en el token ya que el token no varía desde el login. Otra opción sería por ejemplo en Angular generar un servicio que se encargue de la sessión 🙂