Durante el pasado he mostrado en el canal como hacer una API en .net y actualmente estoy creando un curso sobre blazor el cual va a llamar a esta API para hacer back end.
En el mundo real, cuando trabajamos con APIs debemos asegurarlas, incluyendo seguridad, por ello, vamos a ver hoy la forma más común de implementar seguridad a nuestras APIs utilizando JWT o JSON Web Tokens
Antes de empezar con el vídeo decir que no vamos a ver como implementar JWT en código, sino que va a ser una vista general de que es JWT y es aplicable a cualquier lenguaje.
Índex
1 - Para qué sirven los Tokens de seguridad
Para comprender que es un JWT debemos entender que es un token de seguridad (security token) y cual es su objetivo.
Como su nombre indica un token de seguridad es un token, el cual es una cadena de texto, que nos proporciona información sobre dicho token. Esta información es por ejemplo, el creador del token (issuer), el tiempo de vida del token, quizá premios de tu usuario o el propio nombre de usuario, etc.
Además estos tokens están normalmente firmados de una forma simétrica o asimétrica, dependiendo de la tecnología utilizada, pero la idea detrás es la misma, evitar una modificación o falsificación de los mismos.
Por ende, los tokens de seguridad sirven para identificar al usuario o cliente que está utilizando el servicio.
2 - Qué es JWT (Json Web Token)
JWT es un formato popular (el más popular) de token de seguridad, el cual está en formato de JSON pero codificado en base64 para poder trabajar y transferirlo a través de HTTP con mayor facilidad.
Para que este token tenga efecto, lo enviaremos en la cabecera de la petición HTTP como parte de la autenticación bearer.
Pero no es el único token de seguridad, existen también tokens SAML o SWT.
Nota: imagen utilizando Postman en el que muestro la Autorización
2.1 - Partes de un Json web token
Como he mencionado anteriormente en el token podemos incluir información, como puede ser el nombre de usuario o los permisos.
Para explicar las partes que contiene un token, vamos a ver un simple ejemplo:
Como podemos observar, este tiene diferentes apartados:
2.1.1 - Cabecera
Contiene el algoritmo y el tipo de token
{
"alg": "HS256",
"typ": "JWT"
}
2.1.2 - Cuerpo
Contiene los datos, aquí es donde incluimos el nombre de usuario, los permisos, etc, en general la información que queremos tener disponible; también es muy común denominar a este aspecto “los claims”.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Nota: Esta información no está encriptada, por lo que cualquiera con acceso al token puede leerlo, no hay que poner información sensible como contraseñas en el token.
2.1.3 - Firma
Finalmente el espacio donde entra la firma del servicio que crea el token.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
2.1.4 - Resultado final
También podemos observar el resultado final que vamos a recibir y como vemos, cada uno de los tres apartados es separado por el carácter punto.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
3 - Diferencia entre Autenticación y Autorización
Cuando tratamos el tema de JWT o de permisos nos viene siempre a la mente las palabras autenticar y autorizar.
Primero una pequeña descripción:
Autenticar es el proceso de comprobar la identidad del usuario utilizando comúnmente credenciales, por ejemplo usuario y contraseña.
Autorización es una vez estamos autenticados, el proceso de comprobar que ese usuario tiene los permisos para acceder al sistema.
El proceso de autorización (y autenticación) puede estar administrado por el mismo server que la autorización o no, por ejemplo, es muy común hoy en día delegar esta autenticación a servicios como Google o Facebook. (Lo típico que vemos en las webs de “haz login con google”). y es aquí donde entra OAuth.
3.1 - Qué es OAuth?
OAuth es un estándar para la autorización y cualquiera puede implementarlo.
Es por eso que he mencionado que puede venir desde nuestro servidor o desde otro cómo puede ser google.
3.2 - Qué es OAuth2?
Como bien imaginamos es la versión 2 del protocolo OAuth, simplifica la versión anterior y facilita su uso entre aplicaciones.
Como está mencionado anteriormente, la gran ventaja de utilizar OAuth es que delegamos la autenticación y la autorización de nuestros usuarios en servicios de terceros (como google o facebook).
Esta funcionalidad es muy grande para muchas webs, pues únicamente necesitan el nombre de usuario, por ejemplo para comentar en un post.
4 - Diferencias entre JWT y OAuth
En este punto ya tenemos clara la diferencia entre JWT y OAuth (u OAuth2).
JWT es el formato del token de seguridad, mientras que OAuth es el protocolo estándar de autorización que puede utilizar JWT como token.
En un caso de uso real, no debemos preocuparnos de cómo el usuario ha conseguido ese token, sino que cuando llega a nuestra aplicación validarlo y si es válido procesamos la request. Si que es cierto que para realizar logout o cerrar sesión debemos utilizar OAuth2 ya que JWT por sí solo no tiene la habilidad de “cancelar el token” sino que tiene un tiempo de expiración y el token será valido hasta ese momento.
5 - Utilizar JWT en microservicios
Cuando estamos en el mundo de los microservicios utilizar JWT es muy común desde un mismo microservicio o aplicación ir llamando a distintos servicios sin tener que volver a hacer login etc.
Pongámonos en el supuesto de una aplicación, medianamente grande, en la cual tenemos acceso a información sobre películas, actores, series, cada uno de ellos siendo un microservicio.
Al final del día un microservicio es una aplicación que por sí sola es completamente funcional, por lo que si para acceder a dicha información necesitamos ciertos permisos deberemos estar identificados en el sistema.
Pero si nos paramos a pensar no tiene mucho sentido pedirle al usuario que se identifique 3 veces, con una debe ser suficiente. Es aquí donde entra JWT.
Ya bien sea en nuestro propio servidor o en un tercero, haremos login y este nos devolverá un token. Y utilizaremos ese token para ir consultando o solicitando la información de los diferentes servicios.
Este token que solemos recibir es del tipo bearer token para así evitar CFRS (cross site scripting) en nuestras request.
6 - ventajas y desventajas de los json web tokens
6.1 - Ventajas de JWT
Los token JWT son lo que se denomina stateless, no se almacena en el lado del servidor por lo que no consumen memoria.
Con la firma del JWT nos aseguramos su procedencia y validez lo que nos permite confiar en que la request es legítima.
El mismo token nos sirve para múltiples aplicaciones lo que mejora en ciertas ocasiones la experiencia de usuario y por supuesto mejora el desarrollo.
6.2 - Desventajas de JWT
Para mi la mayor desventaja de JWT es que al ser un token válido por X tiempo, si queremos hacer logout o desde la administración denegar el acceso a un token que ya lo tiene debemos esperar o bien a que el tiempo de validez del token finalize o implementar una serie de sistemas como blacklists que añaden mucha complejidad al asunto.
(Por ejemplo si un token ha sido robado)
Como he explicado todo el post, los tokens son validos X tiempo, pero, qué pasa si el tiempo se acaba y queremos seguir logueados. Para ello necesitamos implementar lo que se denomina Refresh tokens, los cuales nos permiten refrescar los tokens para que sigan siendo válidos.
Conclusión
En este post hemos visto qué son y para qué se utiliza JWT así como Oauth/Oauth2
Las diferencias entre JWT y OAuth
Cómo se utiliza JWT en los microservicios y cuales son las ventajas y desventajas de JWT.