JWT (JSON Web Token) es un estándar abierto (RFC 7519) para transmitir información de forma segura entre partes como un objeto JSON compacto y URL-safe. Los JWT codifican claims (aseveraciones sobre una entidad) que se firman digitalmente usando algoritmos criptográficos, permitiendo autenticación y autorización stateless en aplicaciones web y APIs.
Cómo funciona JWT
Los JWT consisten en tres partes codificadas en Base64URL separadas por puntos: header, payload y signature. El header identifica el tipo de token y el algoritmo de firma. El payload contiene claims (ID de usuario, roles, tiempo de expiración). La signature asegura la integridad del token combinando el header codificado, el payload codificado y una clave secreta usando el algoritmo especificado.
Cuando un usuario se autentica, el servidor genera un JWT conteniendo claims de identidad y lo firma con una clave secreta. El cliente almacena el JWT (típicamente en localStorage o cookies) y lo incluye en solicitudes subsecuentes vía el header Authorization. Los servidores verifican la signature y extraen los claims sin almacenar session state—permitiendo autenticación stateless.
Los JWT soportan dos tipos de seguridad: tokens firmados (JWS) verifican integridad y autenticidad usando algoritmos HMAC, RSA o ECDSA. Tokens encriptados (JWE) proporcionan confidencialidad encriptando el contenido del payload. La mayoría de implementaciones usan tokens firmados para autenticación, confiando en TLS para seguridad en transporte.
Cuándo usar JWT
Usa JWT cuando necesitas:
- Autenticación stateless para APIs y microservicios
- Single sign-on (SSO)Across múltiples aplicaciones
- Authorization claims embebidos en el token (roles, permisos)
- Aplicaciones móviles y SPAs que requieren token-based auth
- Sistemas de identidad federada que pasan identidad entre servicios
- Access tokens de corta duración con refresh tokens opcionales
No uses JWT cuando necesitas:
- Server-side session management con revocación inmediata
- Datos altamente sensibles que requieren encryption at rest
- Claims grandes que exceden recomendaciones de tamaño de token (>8KB)
- Actualizaciones frecuentes de claims que requieren propagación inmediata
- Requerimientos de compliance para registrar actividad de sesión en servidor
Señales de que necesitas JWT
- Arquitectura de API stateless escalando horizontalmenteAcross servidores
- Microservicios que requieren propagación de identidad sin central session store
- Aplicaciones móviles incapaces de usar server-side sessions eficientemente
- Single sign-onAcross múltiples dominios o aplicaciones
- Aplicaciones de terceros que acceden a tus APIs en nombre de usuarios
- Necesidad de embeber decisiones de autorización directamente en tokens
Métricas y medición
Métricas de seguridad:
- Token validation success rate: Porcentaje de tokens validando exitosamente (objetivo: >99%)
- Invalid token attempts: Validaciones fallidas por expiración, mala signature o tokens malformados
- Token replay prevention: Cero ataques de replay exitosos (implementar nonces o expiración corta)
- Algorithm confusion attacks: Cero instancias (prevenir validando algoritmo explícitamente)
Métricas de rendimiento:
- Token generation time: Tiempo para crear y firmar JWT (típicamente bajo 5ms)
- Token validation time: Tiempo para verificar signature y extraer claims (típicamente bajo 2ms)
- Token size: Header + payload + signature bytes (objetivo: bajo 4KB para la mayoría de casos de uso)
- Bandwidth overhead: Token transmitido con cada solicitud autenticada
Métricas operacionales:
- Token expiration rate: Porcentaje de solicitudes fallando por tokens expirados
- Refresh token usage: Frecuencia de operaciones de token refresh
- Claim size distribution: Tamaño promedio y máximo de payloadAcross tokens
Según best practices de OAuth 2.0 (RFC 8725), los JWT access tokens deben tener lifetimes cortos (5-60 minutos) para limitar exposición por robo de token. Los refresh tokens permiten sesiones más largas sin comprometer seguridad del access token.
Estructura de JWT
Header
{ "alg": "HS256", "typ": "JWT"}Identifica tipo de token y algoritmo de firma (HMAC, RSA, ECDSA). Codificado en Base64URL.
Payload
{ "sub": "user123", "name": "John Doe", "role": "admin", "iat": 1712345678, "exp": 1712349278}Contiene claims: registered claims (iss, sub, aud, exp, iat, nbf), public claims y private claims. Codificado en Base64URL.
Signature
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)Asegura integridad del token. La verificación confirma que el token no fue manipulado. El algoritmo debe coincidir con el header.
Casos de uso reales
API Authentication
- Autenticación stateless para APIs REST y GraphQL
- Autenticación de microservicios sin central session store
- Bearer token authentication en header Authorization
- Claims-based authorization (roles, permisos, scopes)
Single Sign-On (SSO)
- Propagación de identidadAcross múltiples aplicaciones
- Autenticación federada entre organizaciones
- OIDC (OpenID Connect) ID tokens para identidad de usuario
- Session managementAcross dominios
Aplicaciones móviles
- Token-based auth para iOS, Android, React Native
- Autenticación persistente sin server sessions
- Almacenamiento seguro de credenciales con refresh tokens
- Capacidad offline con tokens en caché
Autorización de terceros
- OAuth 2.0 access tokens para delegación de acceso a API
- Service-to-service authentication
- Machine-to-machine (M2M) communication
- API gateway authentication
Workflows stateless
- Tokens de reset de password con expiración
- Tokens de verificación de email
- Tokens de acción única (invitation links, magic links)
- Grants de acceso temporal
Errores comunes y soluciones
Error: Almacenar datos sensibles en el payload del JWT sin encryption Solución: Los payloads JWT están codificados en Base64, no encriptados. Cualquiera puede decodificarlos. Almacena solo claims no sensibles (ID de usuario, roles). Nunca almacenes passwords, tarjetas de crédito o PII. Usa JWE para payloads encriptados si es necesario.
Error: Usar access tokens de larga duración Solución: Los access tokens deben expirar en 5-60 minutos. Usa refresh tokens para sesiones largas. Implementa token rotation para refresh tokens. Los access tokens de larga duración aumentan la ventana de exposición por robo de token.
Error: No validar el algoritmo del token Solución: Valida que el algoritmo coincida con el valor esperado (HS256, RS256). Rechaza tokens con algoritmo “none”. Los algorithm confusion attacks explotan desajustes entre el algoritmo en el header y la lógica de verificación.
Error: Almacenar JWT en localStorage vulnerable a XSS Solución: Almacena JWT en cookies HttpOnly, Secure, SameSite. Esto previene acceso de JavaScript (protección XSS). Se requiere protección CSRF para cookies. Evalúa trade-offs: localStorage (riesgo XSS) vs cookies (riesgo CSRF).
Error: No implementar revocación de tokens Solución: Los JWT no pueden revocarse antes de expirar sin infraestructura adicional. Implementa token blacklist, tiempos de expiración cortos o invalidación basada en versión. Balancea seguridad con beneficios stateless.
Error: Usar JWT para server-side sessions Solución: Los JWT permiten auth stateless. Si necesitas revocación inmediata, logging en servidor o datos de sesión grandes, usa server-side sessions tradicionales. No fuerces JWT cuando las sesiones son más apropiadas.
Preguntas frecuentes
¿Cuál es la diferencia entre JWT y session tokens? Los session tokens referencian datos de sesión en servidor. Los servidores deben buscar session state. Los JWT embeben claims directamente en el token, permitiendo autenticación stateless sin almacenamiento en servidor. Las sesiones permiten revocación inmediata; los JWT proporcionan escalabilidad stateless.
¿Cómo invalido un JWT antes de su expiración? Los JWT no pueden invalidarse sin infraestructura adicional. Opciones: implementar token blacklist (requiere estado), usar tiempos de expiración cortos, incluir version claim invalidada en cambio de password, usar refresh tokens con capacidad de revocación inmediata.
¿Debo usar firmas HMAC o RSA? HMAC (HS256) usa secreto compartido—simple, rápido, pero ambas partes comparten el secreto. RSA (RS256) usa par de llaves público/privado—el emisor firma con llave privada, los verificadores usan llave pública. Usa HMAC para deployments de un solo servicio. Usa RSA para arquitecturas multi-servicio donde los servicios verifican sin capacidad de firmar.
¿Qué claims debo incluir en JWT? Incluye los claims mínimos necesarios: subject (ID de usuario), issuer, audience, expiration (exp), issued-at (iat). Agrega authorization claims: roles, permisos, scopes. Evita datos sensibles (PII, passwords). Mantén el payload pequeño (bajo 4KB) para minimizar overhead de bandwidth.
¿Se puede encriptar el payload del JWT? Sí, JWT soporta encryption a través de JSON Web Encryption (JWE). JWE encripta el contenido del payload para confidencialidad. La mayoría de implementaciones usan JWTs firmados (JWS) confiando en TLS para seguridad en transporte. Usa JWE cuando el payload contiene datos sensibles o el token puede ser logueado.
¿Cómo manejo JWT en microservicios? El API gateway valida JWT y propaga identidad de usuario a los servicios. Los servicios verifican signature usando secreto compartido (HMAC) o llave pública (RSA). Los servicios extraen claims para decisiones de autorización. El manejo de refresh token se centraliza en el auth service.
¿Cuál es la diferencia entre access token y refresh token? Los access tokens autorizan acceso a API y tienen lifetimes cortos (minutos). Los refresh tokens obtienen nuevos access tokens y tienen lifetimes largos (días, semanas). Los access tokens se envían con cada solicitud; los refresh tokens se usan solo para token refresh. Los refresh tokens requieren almacenamiento seguro.
Cómo aplica en la práctica
JWT permite autenticación stateless crítica para arquitecturas de API modernas. Los microservicios verifican tokens independientemente sin central session store. Las aplicaciones móviles y SPAs usan token-based auth para experiencia de usuario fluida.
Estrategia de implementación:
- Elegir algoritmo de firma (HMAC para simplicidad, RSA para multi-servicio)
- Definir estructura de claims: subject, issuer, audience, expiration, authorization claims
- Implementar generación de token con gestión segura de llaves secretas
- Desplegar middleware de validación de token en API gateways y servicios
- Manejar expiración de token con refresh tokens
- Implementar almacenamiento seguro de token (cookies HttpOnly para web, secure storage para móvil)
Best practices de seguridad:
- Usar access tokens de corta duración (5-60 minutos)
- Validar algoritmo, expiración, issuer, audience
- Almacenar secretos de forma segura (environment variables, secret management)
- Implementar token refresh con refresh token rotation
- Usar HTTPS para toda transmisión de tokens
- Implementar rate limiting en endpoints de validación de tokens
Decisiones de arquitectura:
- Usar JWT para APIs y microservicios stateless
- Considerar server-side sessions para aplicaciones que requieren revocación inmediata
- Implementar patrón de API gateway para validación centralizada de tokens
- Usar llaves asimétricas (RSA, ECDSA) para verificación multi-equipo
- Planificar para token refresh y session management
JWT en Azion
Azion Functions valida JWT en el edge:
- Validación de JWT en Functions antes de reenviar solicitudes al origen
- Firewall rules aplican requerimientos de autenticación
- Extracción de claims para decisiones de autorización en el edge
- Rate limiting previene abuso de validación de tokens
- Real-Time Metrics monitorea eventos de autenticación
- Caché para llaves públicas (RS256) o endpoints JWKS
La red distribuida de Azion autentica solicitudes globalmente, reduciendo latencia para validación de tokens y protegiendo infraestructura de origen.
Aprende más sobre Functions, API Security y Firewall.
Fuentes
- IETF. “RFC 7519: JSON Web Token (JWT).” https://tools.ietf.org/html/rfc7519
- IETF. “RFC 8725: JSON Web Token Best Current Practices.” https://tools.ietf.org/html/rfc8725
- OAuth 2.0 Security Best Current Practices. https://oauth.net/2/oauth-best-practice/
- OpenID Connect Core 1.0. https://openid.net/specs/openid-connect-core-1_0.html