JSON Web Token (JWT) es un estándar abierto (RFC 7519) para la transferencia segura de información entre partes en forma de objeto JSON. JWT se utiliza ampliamente para la autenticación y autorización en aplicaciones web y API modernas. En este artículo, analizaremos en detalle cómo funcionan los tokens JWT, de qué están hechos y cómo usarlos de forma segura.
¿Qué es JWT?
JWT (pronunciado "jot") es una forma compacta y segura para URL de representar reclamos entre dos partes. El token consta de tres partes separadas por puntos: Header.Payload.Signature. Cada parte está codificada en Base64URL.
A diferencia de las sesiones tradicionales, donde el servidor almacena el estado del usuario, JWT es sin estado: toda la información necesaria está contenida en el propio token. Esto hace que JWT sea ideal para sistemas distribuidos y arquitecturas de microservicios.
Estructura del token JWT
Encabezado (Encabezado)
El encabezado generalmente contiene dos campos: tipo de token (typ) y algoritmo de firma (alg). Los algoritmos más comunes son HS256 (HMAC con SHA-256) y RS256 (RSA con SHA-256).
Encabezado de ejemplo:
{
"alg": "HS256",
"typ": "JWT"
}
Carga útil (Carga útil)
Payload contiene afirmaciones: declaraciones sobre el usuario y metadatos adicionales. Hay tres tipos de reclamaciones:
- Reclamaciones registradas — campos estándar:
iss(emisor),exp(fecha de vencimiento),sub(asunto),aud(audiencia),iat(hora de creación) - Reclamos públicos - definidos en el registro de la IANA o tienen un URI para evitar colisiones
- Reclamaciones privadas — campos arbitrarios acordados entre las partes (por ejemplo,
user_id,role)
Ejemplo de carga útil:
{
"sub": "1234567890",
"name": "John Doe",
"role": "admin",
"iat": 1516239022,
"exp": 1516242622
}
Firma (Firma)
La firma se crea codificando el Encabezado y la Carga útil en Base64URL, uniéndolos con un punto y firmando con una clave secreta. La firma garantiza que el token no ha sido modificado desde su creación.
Para HS256, la fórmula se ve así:
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
Cómo funciona la autenticación JWT
El proceso de autenticación con JWT normalmente se ve así:
- Login: El usuario envía sus credenciales (email + contraseña) al servidor
- Generación de token: El servidor verifica los datos y, si son correctos, crea un JWT con los reclamos necesarios
- Almacenamiento: El cliente almacena el token (generalmente en localStorage o cookie httpOnly)
- Enviando solicitudes: En cada solicitud, el cliente agrega un token al encabezado
Authorization: Bearer <token> - Verificación: El servidor verifica la firma del token y extrae los datos del usuario de la carga útil
Ventajas de JWT
- Sin estado: El servidor no necesita almacenar sesiones en la base de datos o en la memoria
- Escalabilidad: Ideal para microservicios: cualquier servicio puede verificar el token
- Dominio cruzado: JWT es fácil de usar entre diferentes dominios y servicios
- Compacidad: El tamaño pequeño permite pasar token en URL, parámetros POST o encabezados
- Autosuficiencia: Toda la información para la autorización está contenida en el token
Seguridad JWT: mejores prácticas
1. Establezca siempre una fecha de vencimiento
Nunca cree tokens sin el reclamo exp. La vida útil recomendada de un token de acceso es de 15 minutos a 1 hora. Para sesiones más largas, utilice tokens de actualización.
2. Utilice cookies httpOnly
En lugar de localStorage, es mejor almacenar JWT en cookies httpOnly, a las que JavaScript no puede acceder. Esto protege contra ataques XSS. Además, marque las casillas Secure y SameSite.
3. No almacene datos confidenciales en la carga útil
La carga útil solo está codificada en Base64, no cifrada. Cualquiera puede decodificarlo. Nunca incluya contraseñas, números de tarjetas de crédito u otra información confidencial.
4. Utilice algoritmos confiables
Evite el algoritmo none. Para una firma simétrica, utilice HS256 con un secreto largo (mínimo 256 bits).Para asimétrico: RS256 o ES256.
5. Validar todas las reclamaciones
Al verificar un token, verifique siempre: exp (no vencido), iss (emisor correcto), aud (audiencia correcta). No confíes en un token solo si tiene una firma válida.
6. Implementar retiro de token
Aunque JWT no tiene estado, a veces es necesario revocar el token (por ejemplo, cuando cierra sesión o cambia su contraseña). Para hacer esto, use una lista negra de tokens o una vida útil corta con tokens de actualización.
Errores típicos al trabajar con JWT
- Falta de verificación de firma es el error más peligroso que le permite falsificar un token
- Usar un secreto débil: los secretos breves o predecibles pueden detectarse mediante fuerza bruta
- Almacenamiento en localStorage — Vulnerabilidad a ataques XSS
- La caducidad es demasiado larga: aumenta la ventana de ataque cuando el token está comprometido
- Transmisión a través de URL — el token puede terminar en los registros del servidor y en el historial del navegador
JWT frente a sesiones: cuándo usar qué
JWT es mejor para:
- Aplicaciones de página única (SPA) con una API independiente
- Arquitectura de microservicio
- Aplicaciones móviles
- Sistemas con inicio de sesión único(SSO)
Las sesiones tradicionales son mejores para:
- Aplicaciones web de servidor (Laravel, Rails, Django)
- Aplicaciones que requieren revocación de acceso inmediata
- Proyectos simples sin arquitectura compleja
Práctica: decodificación JWT
¿Quieres ver qué hay dentro de un token JWT? Utilice nuestro decodificador JWT: desmonta el token en componentes, muestra el encabezado, la carga útil y verifica la firma. Esta es una herramienta útil para los desarrolladores a la hora de depurar la autenticación.
Conclusión
Los tokens JWT son un poderoso mecanismo de autenticación para aplicaciones modernas. Proporcionan autorización sin estado, son fácilmente escalables y funcionan entre diferentes servicios. Lo principal es seguir las reglas de seguridad: establecer la fecha de vencimiento, utilizar algoritmos confiables, almacenar tokens de forma segura y validar todos los reclamos. Cuando se usa correctamente, JWT simplifica enormemente la arquitectura y mejora el rendimiento de la aplicación.