Decodificar un JSON Web Token (JWT)
- Panel
- Documentación
- API
¿Qué es un JWT (JSON Web Token)?
Un JSON Web Token, abreviado JWT (pronunciado "jot"), es un formato compacto definido por la RFC 7519 que permite transportar una serie de revindicaciones (claims) entre dos partes. El JWT, o jeton JWT, es hoy el formato dominante para transportar una identidad autenticada en una API HTTP. Un JWT se presenta como una cadena ASCII compuesta por tres segmentos separados por puntos:
header.payload.signature
Cada segmento está codificado en Base64URL, una variante de Base64 sin padding
= y que sustituye + por - y / por _
para poder circular por una URL o una cabecera HTTP sin escape adicional.
Importante: un JWT NO está cifrado. El formato JWT estándar (JWS) está simplemente firmado: la firma garantiza la integridad del contenido, pero no aporta ninguna confidencialidad. Cualquiera puede decodificar el payload de un JWT con un simple Base64URL inverso, como hace esta herramienta jwt decode en línea.
Anatomía de un JWT
Un json web token se compone de tres partes bien diferenciadas, cada una de las cuales desempeña un papel preciso en el mecanismo de autenticación:
1. Header
El header es un objeto JSON que describe cómo se firma el token. Contiene como mínimo:
alg(algorithm): el algoritmo de firma utilizado. Valores típicos:HS256,RS256,ES256,EdDSA.typ(type): el tipo del token, casi siempre"JWT".kid(key ID): opcional, identifica qué clave debe usarse para verificar la firma. Práctico en presencia de un parque de claves en rotación (JWKS).
2. Payload
El payload contiene las claims, es decir, las revindicaciones que el emisor hace sobre el usuario o la sesión. La RFC 7519 define siete claims estándar (registered claims):
iss(issuer): quién ha emitido el token, por ejemplo"https://accounts.google.com".sub(subject): a quién pertenece el token, en la práctica el identificador de usuario.aud(audience): para quién va destinado el token. Evita que un token emitido para la API A sea aceptado por la API B.exp(expiration time): timestamp Unix tras el cual el token deja de ser válido.nbf(not before): timestamp antes del cual el token todavía no está activo.iat(issued at): timestamp de emisión del token.jti(JWT ID): identificador único del token, utilizado para la revocación y la prevención del replay.
A esas claims estándar suelen añadirse claims personalizadas propias de
la aplicación (roles, scope, tenant_id, email,
permissions...).
3. Firma
La firma es un compendio criptográfico calculado sobre
base64url(header) + "." + base64url(payload) con ayuda de una clave. Es la que prueba
que nadie ha modificado el header ni el payload desde la emisión. Los algoritmos más habituales:
- HS256 / HS384 / HS512: firma simétrica HMAC-SHA. Una clave secreta compartida entre el emisor y el verificador. Sencilla, pero inadecuada en cuanto hay más de un consumidor.
- RS256 / RS384 / RS512: firma asimétrica RSA. El emisor firma con su clave privada, cualquier consumidor verifica con la clave pública correspondiente. Estándar de hecho para OAuth2 y OpenID Connect.
- ES256 / ES384 / ES512: firma asimétrica ECDSA. Mismas propiedades que RS256 pero con claves y firmas mucho más cortas.
- EdDSA (Ed25519): firma asimétrica moderna, rápida y compacta.
Una vez más: la firma protege la integridad, no la confidencialidad. El payload sigue siendo legible para quien tenga el token.
¿Por qué decodificar un JWT?
La operación jwt token decode responde a varias necesidades concretas para un desarrollador o un ingeniero de seguridad:
- Depuración de autenticación: su API devuelve un 401 o un 403, quiere ver
lo que realmente hay en el payload (
sub,scope,roles,exp) en lugar de adivinarlo. - Verificar las claims: confirmar que un token contiene efectivamente la revindicación
esperada (por ejemplo
tenant_idopermissions) antes de buscar en otro punto de la cadena de autorización. - Leer la expiración: convertir el timestamp
expen una fecha humana para confirmar que un token está realmente caducado, o por el contrario que aún debería ser válido. - Auditoría de seguridad: asegurarse de que un servicio de terceros no filtre información sensible en el payload (correos electrónicos, identificadores internos, datos personales).
- Formación y comprensión: ver concretamente cómo es un jsonwebtoken emitido por un proveedor OAuth (Google, Auth0, Keycloak, AWS Cognito) para entender la mecánica sin sumergirse en la documentación.
- Exploración de tokens públicos: inspeccionar un JWT encontrado en logs, en una cookie o en un intercambio OAuth interceptable.
Decoder vs Verifier: la distinción crítica
Las dos operaciones parecen cercanas pero no tienen nada que ver en términos de garantías de seguridad:
- Decodificar un JWT consiste en dividir la cadena por los
.y aplicar un Base64URL inverso a los dos primeros segmentos. Es una simple lectura, al alcance de cualquier script de tres líneas. No se realiza ninguna verificación de firma. - Verificar un JWT consiste en recalcular la firma a partir del header, del payload y de una clave y, después, comparar el resultado con la firma presente en el token. Es lo que garantiza que el token no ha sido falsificado.
Conclusión práctica: decodificar no es confiar. Mientras que la firma no haya sido verificada con la clave correcta, el contenido del payload puede ser totalmente falso. Para la fase de confianza, utilice nuestro JWT Verifier.
Cómo utilizarlo
- Recupere el JWT que inspeccionar, por ejemplo desde una cabecera
Authorization: Bearer <jwt>, desde una cookie de sesión, desde ellocalStoragedel navegador, o desde un log de aplicación. - Pegue la cadena completa en el campo de entrada. Los tres segmentos deben permanecer separados por puntos.
- La herramienta muestra inmediatamente el header decodificado en JSON formateado, con el algoritmo y el tipo.
- El payload se decodifica después y se muestra. En él ve todas las claims estándar y personalizadas.
- La herramienta también indica la información de firma (algoritmo declarado, longitud), sin verificarla.
- Para confirmar que el token no ha sido falsificado, pase a nuestro JWT Verifier con la clave pública o el secreto esperado.
Toda la decodificación se realiza en su navegador en JavaScript: su token nunca se envía a nuestros servidores.
JWT y seguridad: los errores que evitar
NUNCA almacene datos sensibles en el payload de un JWT firmado.
Contraseñas, números de tarjeta bancaria, datos médicos, secretos de API, identificadores internos críticos: todo lo que se encuentra en el payload es legible para quien tenga el token, incluido el propio usuario mediante las herramientas de desarrollo de su navegador. La firma no enmascara nada, solo prueba que el emisor es quien dice ser.
Algunas reglas de oro para utilizar bien los JWT en producción:
- Verifique siempre la firma en el lado del servidor antes de conceder el menor derecho. Nuestro JWT Verifier ilustra exactamente esa operación.
- Prefiera RS256 o ES256 a HS256 para las API públicas. La firma asimétrica evita compartir un secreto entre el emisor y cada consumidor.
- Respete siempre la claim
exp. Un JWT sin expiración o con una expiración demasiado lejana es una bomba de relojería en caso de fuga. - Valide
issyauden el lado del servidor, para evitar que un token legítimo emitido para otro servicio sea aceptado por error. - Rechace
alg: "none"en la verificación. Es un fallo clásico que permite a un atacante forjar cualquier payload. - Mantenga duraciones de vida cortas (15 minutos por ejemplo) y combine con un refresh token más largo pero revocable en el lado del servidor.
Ejemplo de jeton JWT decodificado
Este es un JWT típico:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiSm9obiIsImlhdCI6MTUxNjIzOTAyMn0.jrU9j8LZcRK2_BZjqXjU7lEpJbkqmXfTQIu9vT45j-I
Una vez decodificado, este es su contenido:
// Header
{
"alg": "HS256",
"typ": "JWT"
}
// Payload
{
"sub": "123",
"name": "John",
"iat": 1516239022
}
// Signature (binaire, encodé en Base64URL)
HMACSHA256(
base64url(header) + "." + base64url(payload),
secret
)
¿Dónde encontrar un JWT para copiar?
En la práctica, un JWT que descifrar (en el sentido de decodificar) procede con mayor frecuencia de uno de estos sitios:
- Cookie HTTP: abra las herramientas de desarrollo (F12), pestaña
Application o Storage, después Cookies. Localice una cookie llamada
access_token,jwt,sessiono similar. localStorage/sessionStorage: mismo panel, sección Local Storage. Muchas SPA almacenan ahí su token con una clavetokenoauth.- Cabecera
Authorization: pestaña Network, seleccionar una petición a la API, leer la cabeceraAuthorization: Bearer <jwt>. Copiar únicamente la parte después deBearer. - Logs del servidor: un JWT aparece a veces en los logs de una pasarela o de un reverse proxy (a evitar en producción, pero útil en depuración).
Preguntas frecuentes
¿El JWT está cifrado o en claro?
Un JWT firmado (formato JWS) solo está codificado en Base64URL, no cifrado. Cualquier persona que intercepte un token puede leer el payload en pocos segundos. Si debe transportar datos realmente confidenciales en el token, hay que utilizar el formato JWE (JSON Web Encryption), que añade una capa de cifrado por encima de la firma. En la práctica, el JWE sigue siendo raro: se prefiere no poner datos sensibles en un jeton y conservar la información crítica en una base de datos en el lado del servidor.
¿Cómo revocar un JWT antes de su expiración?
Es uno de los puntos débiles del JWT: por construcción, el servidor no necesita almacenar
el estado del token, así que tampoco sabe cómo marcarlo como revocado. Existen tres enfoques.
Lista de revocación: mantener en el lado del servidor la lista de
jti invalidados y consultarla en cada petición. Duraciones de vida cortas:
emitir access tokens válidos de 5 a 15 minutos y utilizar un refresh token revocable en el lado del
servidor para generar nuevos. Rotación de clave de firma: invalidar
toda una generación de tokens cambiando la clave. El segundo enfoque es, con diferencia, el más
extendido.
¿Qué diferencia hay entre un JWT y una sesión clásica?
Una sesión clásica almacena un identificador opaco en el lado del cliente (normalmente en una cookie) y conserva todos los datos asociados (usuario, derechos, expiración) en memoria o en base de datos en el lado del servidor. Un JWT, por el contrario, transporta directamente esos datos en el token firmado. Ventaja del JWT: el servidor no necesita almacenar sesión, lo que simplifica el escalado horizontal y la arquitectura de microservicios. Inconvenientes: la revocación es más compleja, el token es más voluminoso en cada petición y la menor fuga expone el payload.
¿Diferencia entre JWT, JWS y JWE?
JWT (RFC 7519) es un formato de jeton genérico. Puede implementarse de dos maneras concretas: JWS (RFC 7515, JSON Web Signature) que se limita a firmar el payload, y JWE (RFC 7516, JSON Web Encryption) que lo cifra. En la práctica, cuando se habla de "JWT" sin precisión, casi siempre se habla de un JWS: un token firmado pero legible para todos. El JWE se utiliza en contextos donde la confidencialidad del payload es indispensable, por ejemplo en algunos escenarios OpenID Connect avanzados.
Mi JWT no es aceptado por la API, ¿por qué?
Las causas habituales son, por orden de frecuencia: token caducado (compruebe
la claim exp), firma no válida (la clave secreta o pública
no coincide con la utilizada por el emisor), mal aud
(el token se ha emitido para otro servicio), mal iss
(el emisor declarado no es el esperado), algoritmo rechazado (la API exige
por ejemplo RS256 y recibe un HS256), relojes desincronizados entre
el emisor y el verificador (afecta a exp y nbf). Decodificar el
token con esta herramienta permite ya eliminar la mitad de las hipótesis leyendo directamente las
claims.
¿Cómo generar un JWT?
La mayoría de lenguajes dispone de una biblioteca dedicada: jsonwebtoken en
Node.js, PyJWT en Python, lcobucci/jwt o
firebase/php-jwt en PHP, jjwt en Java, golang-jwt/jwt
en Go. Todas toman como entrada un objeto payload, una clave y un algoritmo, y devuelven la
cadena header.payload.signature lista para enviarse. Se desaconseja encarecidamente
implementar la generación a mano: la criptografía tiene demasiados riesgos (comparaciones
no en tiempo constante, gestión incorrecta de alg: none, etc.).
¿Acepta el decoder un JWT caducado?
Sí. El decoder se limita a mostrar el contenido del token sin emitir juicio sobre su
validez temporal. No evalúa ni exp, ni nbf, ni la firma.
Es útil para entender por qué una API ha rechazado un token: se puede
comparar el valor de exp con la hora actual para confirmar que está realmente
caducado.
¿Mi JWT es válido si el decoder lo muestra correctamente?
No. La visualización prueba únicamente que la cadena está bien formada (tres segmentos separados por puntos, codificación Base64URL correcta, JSON válido en el header y el payload). No dice nada sobre la autenticidad del token. Un JWT totalmente falsificado puede mostrarse sin error en un decoder; precisamente por eso hay que pasarlo a un verifier.
Ejemplo de solicitud
curl -X POST https://cdrn.fr/api/v1/tools/jwt-decoder/execute \
-H "Content-Type: application/json" \
-d '{"token":"..."}'
Esquema de entrada
| Campo | Tipo | Obligatorio | Por defecto |
|---|---|---|---|
token |
text | ✓ | – |
Puntos de acceso
GET https://cdrn.fr/api/v1/tools- lista todas las herramientas disponiblesGET https://cdrn.fr/api/v1/tools/jwt-decoder- recupera el esquema de esta herramientaPOST https://cdrn.fr/api/v1/tools/jwt-decoder/execute- ejecuta esta herramienta con un payload JSON