El JSON Web Token, comúnmente conocido como JWT, es un estándar abierto para la transmisión segura de información entre partes. Se define bajo la especificación RFC 7519 y se utiliza, principalmente, en el contexto de la seguridad web para autenticar usuarios y asegurar la integridad de los datos.
Contenidos
Estructura de un JWT
Un JWT se compone de tres partes codificadas en Base64Url, separadas por puntos:
- Header: Contiene metainformación sobre el token, como el tipo y el algoritmo de firma utilizado. Por ejemplo:
{"alg": "HS256", "typ": "JWT"}
{"sub": "1234567890", "name": "John Doe", "admin": true}
Por ejemplo, la firma se genera a partir de:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret)
Tipos de reclamaciones en un JWT
Las reclamaciones o claims se dividen generalmente en tres categorías:
Reclamaciones registradas
Son un conjunto de reclamaciones predefinidas que son recomendadas para su uso en JWT. Entre ellas se encuentran:
- iss: El emisor del token.
- sub: El sujeto del token.
- aud: El público objetivo del token.
- exp: Fecha de expiración del token.
- nbf: Indica el momento en el cual el token es válido.
Reclamaciones públicas
Las reclamaciones que pueden ser definidas a voluntad por los usuarios, pero deben evitar colisiones de nombres. Por ejemplo:
- username: Nombre de usuario del individuo autenticado.
- role: Rol del usuario (admin, usuario regular, etc.).
Reclamaciones privadas
Reclamaciones personalizadas que se crean para compartir información entre partes de manera que no interferirán con las reclamaciones registradas o públicas.
¿Cómo funciona un JWT en seguridad web?
El flujo de trabajo de un JWT generalmente sigue estos pasos:
Autenticación
El proceso inicia cuando un usuario se autentica correctamente, generalmente a través de un formulario de inicio de sesión. Una vez que se verifica el usuario, el servidor genera un JWT que contiene información sobre la sesión del usuario.
Generación del Token
Después de la autenticación, el servidor crea un JWT y lo envía como respuesta al cliente. Este token puede ser almacenado en el localStorage o como una cookie en el navegador.
Envío del Token
Con cada petición posterior, el cliente envía el JWT al servidor, generalmente a través del encabezado Authorization:
Authorization: Bearer
Verificación del Token
El servidor recibe el token y lo verifica utilizando la clave secreta o el certificado. Si el token es válido y no ha expirado, el acceso a los recursos protegidos es otorgado.
Ventajas del uso de JWT
El uso de JWT en aplicaciones web tiene varias ventajas:
Escalabilidad
Los JWT son autónomos, lo que significa que los servidores no necesitan mantener una sesión de usuario en memoria. Esto mejora la escalabilidad, ya que múltiples instancias de servidor pueden manejar peticiones sin necesidad de acceso a la base de datos para verificar el estado de la sesión.
Interoperabilidad
Al ser un estándar abierto, JWT es interoperable entre distintos lenguajes de programación y plataformas. Esto facilita la integración en diversos sistemas y servicios.
Seguridad
La capacidad de firmar el JWT asegura que el contenido no ha sido alterado, y la utilización de algoritmos de encriptación añade una capa adicional de seguridad, proporcionando confidencialidad cuando se requiere.
Desventajas del uso de JWT
A pesar de sus ventajas, también existen desventajas al implementar JWT:
Tamaño del Token
Los JWT pueden volverse grandes, especialmente si contienen mucha información en el payload. Esto puede llevar a una mayor sobrecarga en la red si se envían en cada solicitud.
Expiración y Revocación
Una vez emitido, un JWT es válido hasta que expire. Si un usuario necesita ser revocado (por ejemplo, si su cuenta ha sido comprometida), el servidor debe implementar un mecanismo adicional, como listas de revocación, ya que el token puede seguir siendo utilizado hasta que expire.
Gestión de Claves
La seguridad del JWT depende de la fuerza de la clave utilizada para firmar el token. Mantener esta clave segura y rotarla periódicamente es crucial para la seguridad de la aplicación.
Usos Comunes de JWT
Los JWT son utilizados en una variedad de aplicaciones y contextos, entre ellos:
Autenticación de APIs
En aplicaciones que utilizan APIs RESTful, JWT se usa frecuentemente para autenticar peticiones. Permite a los desarrolladores de APIs construir una arquitectura que sea tanto segura como fácil de usar.
Autenticación entre Microservicios
En arquitecturas de microservicios, los JWT facilitan la autenticación entre servicios al proporcionar una forma sencilla de verificar a los usuarios sin necesidad de compartir sesiones entre servicios.
SSO (Single Sign-On)
La implementación de JWT puede facilitar la implementación de soluciones de SSO, permitiendo a los usuarios autenticarse una sola vez y acceder a múltiples aplicaciones sin la necesidad de volver a iniciar sesión.
Compartición Segura de Información
Los JWT también son útiles para compartir información entre diferentes partes, garantizando la integridad y autenticidad de los datos transmitidos.
Control de Acceso
Los JWT permiten implementar controles de acceso finos, ya que se pueden incluir datos sobre roles y permisos directamente en el token.
Implementación de JWT en un Proyecto
Creación de un JWT
Para crear un JWT, se pueden utilizar diversas bibliotecas disponibles en múltiples lenguajes como JavaScript, Python y Java. Un ejemplo en Node.js usando la biblioteca jsonwebtoken
es:
const jwt = require('jsonwebtoken');
const token = jwt.sign({ id: user.id }, 'your-256-bit-secret', { expiresIn: '1h' });
Verificación de un JWT
La verificación de un JWT se realiza de manera similar, utilizando la misma biblioteca:
jwt.verify(token, 'your-256-bit-secret', function(err, decoded) {
if (err) {
return console.log('Token inválido');
}
console.log(decoded); // { id: 123, i Ss: 'your-issuer', ... }
});
Manejo de la Expiración del Token
Para manejar la expiración del token, se debe verificar el tiempo de expiración (claim exp) en el payload antes de dar acceso a los recursos protegidos. Si el token ha expirado, se debe redirigir al usuario para que inicie sesión nuevamente y obtenga un nuevo token.
Uso de Middleware
En muchas aplicaciones, especial y particularmente en el contexto de Node.js con Express, se utiliza un middleware para manejar de forma centralizada la verificación de JWT. Aquí hay un ejemplo básico:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const checkToken = (req, res, next) => {
const token = req.headers['authorization']?.split(' ')[1];
if (!token) return res.sendStatus(401); // No autorizado
jwt.verify(token, 'your-256-bit-secret', (err, decoded) => {
if (err) return res.sendStatus(403); // Prohibido
req.user = decoded; // Guardar información del usuario en el request
next(); // Continuar a la siguiente middleware
});
};
app.get('/protected', checkToken, (req, res) => {
res.send('Este es un recurso protegido.');
});
El JSON Web Token es una herramienta poderosa en la gestión de autenticación y autorización en aplicaciones web. Su estructura sencilla y su capacidad para ser verificado y validado facilitan la implementación de sistemas seguros, escalables e interoperables. Sin embargo, se deben tener en cuenta las mejores prácticas y la gestión adecuada de la seguridad para maximizar su efectividad.