JSON WEB TOKEN es un mecanismo para poder propagar entre dos partes
y de forma segura, la identidad de un determinado usuario.
Vamos a explicar primero el funcionamiento de JWT, después el ejemplo práctico.
JSON WEB TOKEN funciona de la siguiente manera: al registrarse o loguearse
el api va devolver el token con los datos de usuario.
Un token se trata de una cadena de texto que tiene tres partes codificadas en Base64,
cada una de ellas separadas por un punto, como la que vemos a continuación:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Podemos utilizar el debugger online de jwt.io para decodificar ese token y visualizar su contenido.
Si accedemos al mismo y pegamos dentro el texto completo, se nos mostrará lo que contiene:
Un token tiene tres partes:
Header
Encabezado dónde se indica el algoritmo y el tipo de token,
que en el caso del ejemplo anterior era el algoritmo HS256 y un token JWT.
Payload
Indica los datos de usuario y privilegios,
y toda la información que se quiera agregar.
Signature
Es una firma que nos permite verificar si el token es válido.
Ahora bien, debemos analizar lo siguiente:
Firma de un token JWT
La firma se construye de tal forma que vamos a poder verificar que el remitente es quien dice ser y que el
mensaje no se ha modificado por el camino.
Se construye como el HMACSHA256, que son las siglas de Hash-Based Message Authentication Code (Código de
Autenticación de Mensajes),
cifrado además con el algoritmo SHA de 256 bits. Se aplica esa función a:
Codificación en Base64 de header, Codificación en Base64 de payload, Un secret establecido por la
aplicación.
De esta forma, si alguien modifica el token por el camino, por ejemplo, inyectando alguna credencial o algún
dato malicioso, entonces podríamos verificar que la comprobación de la firma no es correcta, por lo que no
podemos confiar en el token recibido y deberíamos denegar la solicitud de recursos que nos haya realizado, ya
sea para obtener datos o modificarlos.
Si lo que estamos requiriendo es que el usuario esté autenticado, deberíamos denegar esa petición, por lo que
siempre que trabajemos con JWT deberíamos verificar con esa firma si el token es válido o no lo es.
Aunque el algoritmo nos permita verificar la firma, y, por tanto, confiar o no, tanto el encabezado como el
cuerpo si llevan muchos datos van en abierto, ya que Base64 no es un cifrado, es simplemente una codificación
que es muy fácilmente decodificable.
JWT nos invita siempre a que la comunicación entre partes se realice con HTTPS para encriptar el tráfico, de
forma que, si alguien lo interceptara, el propio tráfico a través de HTTP sobre esos sockets SSL, cifrara toda
la comunicación, la del token y todo lo demás, y así añadir esa posibilidad de seguridad.
De hecho, siempre deberíamos utilizar HTTPS y un servidor con certificado para hacer el despliegue de nuestras
aplicaciones, no solamente con este con este tipo de token JWT.
Ahora si, vamos al ejemplo: Podemos usar el API que construimos en el tutorial
anterior
Instalamos JWT a nuestro API, puedes acceder a la librería AQUÍ
Creamos un Middleware que va ejecutar el API al momento de exisitir una petición HTTP
La función va verificar si en los headers de la petición viene el token con el key: x-auth-token.
De existir, estudia si la firma es correcta, de serlo la petición continua, de no serlo el API valida
que no se tiene acceso a la petición.
Al tener nuestro Middleware listo podemos usarlo de forma directa y proteger nuestros endpoints
privados. En este caso vamos al proceso que maneja los Clients, llamamos nuestro Middleware y protegemos las
rutas.
En la linea 15 donde llamamos al endpoint /clients tenemos como segundo argumento la constante auth la
cual se trae el Middleware configurado y le indica a la petición que si no recibe un token válido no muestre la
info.
Intentamos hacer una petición sin envíar ningún token al API y vemos la validación:
Ahora bien, para obtener un token debemos registrarnos o loguearnos en este caso ya que
he configurado el API para que trabaje de dicha manera, el archivo que debes ver es auth.js y
puedes acceder al mismo.
AQUÍ
Cabe destacar que en ambos procesos vamos a usar una función de jwt llamada sign, alli debemos pasar
los objetos que necesitamos para crear el token. En nuestro caso armamos el token con la URI de la db,
un string aleatorio y el tiempo de expiración. Estos datos se encuentran en un .env que por medio de la librería
doenv hemos configurado.
Vamos ejecutar un proceso de autenticación en Postman y luego, al obtener el token del usuario lo envíamos
al endpoint /clients para obtener los datos protegidos.
Como pueden ver, la respuesta al autenticarme de forma correcta devuelve los datos del usuario y el Token
generado por JWT
Ahora, vamos a usar el mismo token para enviarlo a /clients en los headers.
Ahora vemos que si puedo ver la lista de clientes (en este caso tengo un solo record).
Intentemos cambiar el token para ver qué sucede:
De esta forma podemos usar JWT en nuestra API con Node.js y Express.js para proteger nuestros
endpoints.
Pueden descargar el proyecto AQUÍ
Solo queda crear nuestro frontend para completar el ejemplo y eso lo haremos en los siguientes tutoriales.
Saludos!
#JWT
#API
#Javascript
#Nodejs
#Expressjs
#MongoDB
"Una forma de apoyar la creación de contenido técnico y de calidad es donando la cantidad que
creas conveniente, si quieres que haga un post sobre un tema en específico no dudes en avisarme"