- ¿Verifica la firma?
- No, a propósito. Verificar la firma de un JWT requiere el secreto (en tokens HMAC) o la clave pública (en RSA/ECDSA). Pedir eso en una herramienta web de pegar y leer es exactamente como se filtran los secretos: alguien pega un secreto de producción en la pestaña equivocada y acaba en el historial del navegador, en registros de errores o en el autocompletado. Este decodificador lee las partes públicas del token y ahí se detiene. Para verificar, usa la librería JWT que ya tiene tu servidor: jose para Node, PyJWT para Python, jjwt para Java, golang-jwt para Go.
- ¿Qué es un JWT, en un párrafo?
- Un JSON Web Token son tres fragmentos codificados en base64url unidos por puntos: header.payload.signature. El header es JSON como {"alg":"HS256","typ":"JWT"}. El payload es JSON con claims como {"sub":"user_123","exp":1735689600}. La firma es un hash del header+payload calculado con un secreto, así que un servidor con el mismo secreto puede comprobar que nadie alteró el token. La idea: un servidor te da un token, tú lo envías en cada petición y el servidor no necesita una base de datos de sesiones para confiar en ti; basta con verificar la firma.
- ¿En qué se diferencia de jwt.io?
- jwt.io es la referencia y es excelente. Nosotros hacemos menos a propósito (sin verificación de firma, sin firmar), lo que significa que nunca te pedimos pegar un secreto, punto. Ese es el intercambio. Si quieres verificar, usa jwt.io o la librería de tu servidor. Si solo quieres ver qué hay dentro de un token, esto carga más rápido, no tiene anuncios y no te vende Auth0 en la barra lateral.
- ¿Qué son exp, nbf, iat, sub, iss, aud y jti?
- Son los siete claims estándar definidos en el RFC 7519. exp es la fecha de caducidad (segundos Unix: el token deja de ser válido después). nbf es 'not before' (segundos Unix: el token no es válido antes). iat es 'issued at' (segundos Unix: cuándo lo emitió el servidor). sub es el sujeto (normalmente un ID de usuario). iss es el emisor (qué servicio lo emitió). aud es la audiencia (qué servicio debe aceptarlo). jti es un ID único del token (se usa en listas de revocación). Los siete son opcionales; la mayoría de los tokens reales usan sub, iat, exp y a veces iss/aud.
- ¿Por qué la fecha aparece a miles de años de distancia?
- Las fechas de un JWT van en segundos desde el 1970-01-01 UTC, no en milisegundos. Si ves una fecha en el año 50,000 o más, alguien metió por error un valor en milisegundos de Date.now() de JavaScript en un claim del JWT. El token funcionará en la mayoría de las librerías (leen el número que encuentren), pero nunca caducará. Vuelve a emitirlo con Math.floor(Date.now() / 1000).
- El header dice alg: none. ¿Es malo?
- Es el famoso ataque. Algunas librerías JWT de 2014-2016 aceptaban un token con alg: none y se saltaban por completo la verificación de la firma, así que un atacante podía falsificar cualquier payload. Las librerías modernas rechazan alg: none por defecto. Si lo ves en un token real, trátalo como roto: o la librería del emisor está mal configurada o alguien está probando un ataque. Los tokens de producción deberían usar HS256 o RS256.
- ¿Puedo decodificar aquí tokens firmados con RSA (RS256/ES256)?
- Sí. A la decodificación no le importa el algoritmo: solo decodifica las partes en base64url y las muestra. El algoritmo solo importa para verificar (que esta herramienta no hace). Los tokens RS256 y ES256 tienen la misma forma que los HS256; solo cambian los bytes de la firma.
- ¿El token se guarda o se envía a algún sitio?
- No. La página es un archivo HTML estático con un poco de JavaScript. El JavaScript se ejecuta en tu navegador, decodifica y muestra el resultado. No hay fetch, ni localStorage, ni analítica sobre el contenido del token. Cierra la pestaña y el token desaparece. Ni siquiera sabemos que decodificaste uno.