¿Odias los anuncios? Ir Sin publicidad Hoy

Tokens JWT Decodificar, Verificar y Evitar Errores Comunes

Publicado el
Tokens JWT: Decodificar, verificar y evitar errores comunes 1
ANUNCIO · ¿ELIMINAR?
Tokens JWT: Decodificar, verificar y evitar errores comunes

Los tokens JWT aparecen en prácticamente cada aplicación web moderna — encabezados de autenticación, flujos de actualización, control de acceso a APIs. También son uno de los estándares más mal utilizados en el mundo real. Si los estás utilizando, entender qué contiene el token, qué significa decodificar frente a verificar y cuáles de los atajos rompen silenciosamente tu seguridad es imprescindible.

La anatomía de un JWT

Un JWT es tres cadenas base64url codificadas unidas por puntos:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImVtYWlsIjoiYWxpY2VAZXhhbXBsZS5jb20iLCJpYXQiOjE3MTI3NjQ4MDAsImV4cCI6MTcxMjg1MTIwMH0.4Xr8mNkZQWpH2TvL9uY3sKdJwFqBzEcAoMnRiVePxlU
  • Encabezamiento — algoritmo y tipo de token (alg, typ)
  • Carga útil — las declaraciones (los datos que realmente necesita tu aplicación)
  • Firma — firma HMAC o RSA sobre las dos primeras partes

Decodificado, el payload se ve así:

{
  "sub": "user_123",
  "email": "alice@example.com",
  "iat": 1712764800,
  "exp": 1712851200
}

Nada de esto está cifrado. Cualquier persona que tenga el token puede leer estos valores. La firma solo prueba que el token no ha sido alterado después de su emisión — no oculta el contenido.

Decodificar no implica verificar

Esta distinción confunde a más desarrolladores de los que debería.

Decodificar divide el token en los puntos y decodifica cada sección mediante base64url. No se necesita un secreto — cualquier herramienta o línea de comando puede hacerlo. Si deseas decodificar un JWT en línea sin instalar nada, pega el token en IO Tools Decodificador JWT y obtén inmediatamente el desglose del encabezado, carga útil y vencimiento.

Verificar comprueba que la firma es válida utilizando el secreto (o la clave pública para algoritmos asimétricos). También confirma que el token no ha expirado y que las declaraciones coinciden con lo que espera tu aplicación. Omitir la verificación y confiar en un token decodificado es cómo ocurren los bypass de autenticación.

Aquí tienes un fragmento en Node.js que verifica un JWT y maneja los casos comunes:

import jwt from 'jsonwebtoken';

const SECRET = process.env.JWT_SECRET;

function verifyToken(token) {
  try {
    const payload = jwt.verify(token, SECRET, {
      algorithms: ['HS256'],  // whitelist — never allow 'none'
      audience: 'myapp',      // validate aud claim
    });

    // jwt.verify throws if exp is in the past, but be explicit:
    if (payload.exp < Math.floor(Date.now() / 1000)) {
      throw new Error('Token expired');
    }

    return payload;
  } catch (err) {
    // Never silently swallow verification failures
    throw new Error(`Invalid token: ${err.message}`);
  }
}

Declaraciones que merecen validarse

El especificación JWT define declaraciones estándar que tu servidor debe verificar activamente, no solo leer:

ClaimSignificado¿Validar?
expTimestamp de vencimientoSiempre — los tokens obsoletos constituyen una superficie real de ataque
iatTimestamp de emisiónOpcional, útil para comprobaciones de max-age
subAsunto (normalmente ID de usuario)Sí — confirmar que coincida con el usuario esperado
audIntendido para el públicoSí — evita que los tokens de un servicio A se usen en el servicio B

La mayoría de las bibliotecas JWT las validan exp automáticamente — pero solo si las configuras. Lee las documentaciones de tu biblioteca. No asumas que está activa por defecto.

Tres errores que dejan a los desarrolladores en problemas

1. El alg: none Ataque

La especificación JWT permite un valor de algoritmo de none, lo que significa que no hay firma. Algunas bibliotecas — especialmente las más antiguas — aceptan esto y omiten completamente la verificación de firma. Un atacante quita la firma, establece "alg": "none" en el encabezado y forja declaraciones arbitrarias. El servidor las confía.

Solución: blancos explícitamente los algoritmos al verificar. Nunca aceptes none. El fragmento anterior demuestra esto con algorithms: ['HS256'].

2. No validar la expiración

Decodificar un token y confiar en la carga útil sin comprobar exp significa que un token emitido hace meses sigue siendo aceptado. Si una sesión de un usuario ha sido revocada o un atacante ha robado un token antiguo, tu aplicación nunca lo sabrá.

Solución: trate la expiración como obligatoria, no opcional. Para comprobar cuándo un token específico se agota, IO Tools Verificador de vencimiento JWT decodifica el exp declaración y te dice exactamente cuánto tiempo queda — útil para depurar flujos de actualización sin escribir código.

3. Almacenar JWTs en localStorage

localStorage es legible por cualquier JavaScript en la página. Una sola vulnerabilidad XSS significa que un atacante puede exfiltrar silenciosamente el token de autenticación de tu usuario. Aquí cómo se comparan las opciones de almacenamiento:

AlmacenamientoRiesgo XSSRiesgo CSRFAccesible desde JavaScriptNotas
localStorageAltoNingunoEvitar para tokens de autenticación
sessionStorageAltoNingunoMismos riesgos que localStorage
Cookie httpOnlyNingunoMedioNoMejor para autenticación; combinar con SameSite + token CSRF
En memoria (variable JS)BajoNingunoSí (mismo contexto)Perdida en actualización; adecuado para tokens de corta duración

Las cookies httpOnly no pueden ser leídas por JavaScript en absoluto, lo que elimina completamente el vector de robo por XSS. La compensación es la exposición a CSRF, que manejas con SameSite=Strict o un token CSRF.

JWTs frente a sesiones: el verdadero equilibrio

Los JWTs son inestables — el servidor los valida sin necesidad de consultar una base de datos. Esto es útil en sistemas distribuidos donde no se quiere que cada servicio acceda a un almacenamiento compartido de sesiones.

Pero la inestabilidad tiene un costo real: no se puede revocar un JWT antes de que expire. Si un usuario se desconecta o es comprometido, el token permanece válido hasta exp. Existen soluciones (listas de bloqueo de tokens, expiración corta + tokens de actualización), pero añaden complejidad y a menudo recrean lo que ya hace un almacenamiento de sesiones.

Usa JWTs cuando: tienes múltiples servicios autenticando solicitudes de forma independiente, deseas incluir roles y permisos directamente en el token, o tus tokens son de corta duración y la latencia de revocación es aceptable.

Usa sesiones cuando: necesitas revocación inmediata (el cierre de sesión debe funcionar realmente), estás construyendo una aplicación renderizada en el servidor, o la simplicidad supera la escalabilidad inestable.

Inspeccionar un token en segundos

¿Necesitas ver qué contiene un JWT ahora mismo? Terminal:

echo "YOUR.JWT.HERE" | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool

O salta la terminal — pega el token en IO Tools Decodificador JWT para obtener un desglose formateado del encabezado y la carga útil. Ninguna de estas opciones verifica la firma; solo decodifica. Para una lectura rápida de vencimiento sin escribir código, el Verificador de vencimiento JWT te da el timestamp exacto y el tiempo restante.

¿Quieres eliminar publicidad? Adiós publicidad hoy

Instalar extensiones

Agregue herramientas IO a su navegador favorito para obtener acceso instantáneo y búsquedas más rápidas

añadir Extensión de Chrome añadir Extensión de borde añadir Extensión de Firefox añadir Extensión de Opera

¡El marcador ha llegado!

Marcador es una forma divertida de llevar un registro de tus juegos, todos los datos se almacenan en tu navegador. ¡Próximamente habrá más funciones!

ANUNCIO · ¿ELIMINAR?
ANUNCIO · ¿ELIMINAR?
ANUNCIO · ¿ELIMINAR?

Noticias Aspectos técnicos clave

Involucrarse

Ayúdanos a seguir brindando valiosas herramientas gratuitas

Invítame a un café
ANUNCIO · ¿ELIMINAR?