Desarrollo

Cómo decodificar y depurar un JWT

Un JSON Web Token son solo tres partes codificadas en Base64URL. Una vez que sabes leerlas, la mayoría de los errores de «token inválido» se explican solos en segundos. Esta guía muestra cómo decodificar un JWT, revisar los claims que suelen fallar y los errores que convierten los JWT en agujeros de seguridad.

Principiante · 7 min de lectura · Actualizada el 30 de octubre de 2026

Cómo decodificar y depurar un JWT

De qué está formado un JWT

Un JWT tiene este aspecto: xxxxx.yyyyy.zzzzz. Las tres partes, separadas por puntos, son:

  1. Header — JSON con el algoritmo de firma (alg) y el tipo de token, por ejemplo {"alg":"HS256","typ":"JWT"}.
  2. Payload — JSON con los claims: a quién se refiere el token y cuándo es válido.
  3. Firma — un hash de las dos primeras partes, generado con un secreto (HMAC) o una clave privada (RSA, ECDSA).

Las dos primeras partes solo están codificadas, no cifradas. Cualquiera que tenga el token puede leerlas, por eso nunca debes poner contraseñas ni datos personales en el payload de un JWT.

Decodificar un token

Pega el token en el JWT Decoder y te mostrará el header, el payload y todas las marcas de tiempo convertidas en fechas legibles. Funciona en tu navegador, así que los tokens de producción no se envían a ningún sitio. Si prefieres hacerlo a mano, decodifica en Base64URL cada parte —reemplaza - por +, _ por / y añade el padding— o usa Node:

const [header, payload] = token.split('.').slice(0, 2)
  .map(part => JSON.parse(Buffer.from(part, 'base64url').toString()));
console.log(header, payload);

Los claims que más fallan

ClaimSignificadoError típico
expExpiración, en segundos Unix«jwt expired»: revisa también los relojes del servidor y del cliente
nbfNo válido antes deUn token usado unos segundos antes porque el reloj del emisor va adelantado
iatEmitido enRechazado como «emitido en el futuro» por desfase de reloj
audAudiencia a la que va dirigido el tokenUn token de una API enviado a otra: el verificador debe comprobarlo
issEmisorEmisores de desarrollo y producción mezclados

Las marcas de tiempo están en segundos, no en milisegundos. Si una expiración parece del año 55 000, alguien escribió Date.now() en lugar de Math.floor(Date.now() / 1000). El Unix Timestamp Converter lo aclara. La mayoría de las librerías aceptan una pequeña tolerancia de reloj (30–60 segundos) para absorber el desfase entre servidores.

¿Por qué «invalid signature»?

  • Secreto o clave incorrectos — la causa más habitual. Revisa la variable de entorno del servidor que verifica, no solo la del que firma.
  • Algoritmo incorrecto — un token firmado con RS256 que se verifica como HS256, o al revés.
  • El token fue editado — cambiar un solo carácter del payload rompe la firma, y eso es precisamente el objetivo.
  • Rotación de claves — las claves del emisor cambiaron. Con JWKS, relaciona el kid del header con una clave publicada.

Para comprobar a mano un token HS256, calcula HMAC-SHA256 sobre header.payload con el secreto en el HMAC Generator y compáralo, codificado en Base64URL, con la tercera parte.

Errores de seguridad que debes evitar

  • Decodificar no es verificar. Nunca confíes en los claims de jwt.decode(); usa la función de verificación de tu librería con una lista explícita de algoritmos permitidos.
  • Rechaza alg: none y fija el algoritmo: nunca dejes que el token decida cómo se comprueba.
  • Mantén los tokens de vida corta (minutos para los tokens de acceso) y usa refresh tokens para sesiones largas; un JWT no se puede revocar antes de caducar sin estado adicional en el servidor.
  • No guardes tokens en localStorage si un fallo de XSS podría leerlos; para aplicaciones web, una cookie HttpOnly, Secure y SameSite es más segura.

¿Necesitas un token de prueba con claims concretos? Créalo con el JWT Encoder.

Preguntas frecuentes

¿Puede cualquiera leer mi JWT?
Sí. El header y el payload solo están codificados en Base64URL. La firma impide que los modifiquen, pero no que los lean. Usa JWE (tokens cifrados) si el contenido debe mantenerse en secreto.
¿Es seguro pegar un token en un decodificador online?
Solo si se ejecuta en local. El JWT Decoder de devpack decodifica en tu navegador y no envía nada; evita las herramientas que envían el token a un servidor, sobre todo con tokens de producción.
¿Qué significa «jwt malformed»?
La cadena no tiene tres partes en Base64URL separadas por puntos. Suele pasar porque quedó «Bearer » delante del token o porque se copió incompleto.

Sigue leyendo