Escribe el payload
El JSON que quieras: el identificador de usuario, los roles, lo que tu aplicación espere. Se codifica tal cual dentro del token.
Escribe tu propio payload en JSON y obtén el token firmado. Con firma correcta o rota a propósito, y fechas de emisión y expiración automáticas. La clave nunca sale de tu navegador.
100 % privado. No hay servidor: los datos se generan en tu navegador y no se envían ni se guardan en ninguna parte.
Cómo funciona
El JSON que quieras: el identificador de usuario, los roles, lo que tu aplicación espere. Se codifica tal cual dentro del token.
Con firma correcta para el camino feliz. Con firma rota para comprobar que tu backend rechaza el token en vez de confiar en su contenido.
Sale listo para pegar en la cabecera Authorization, en una prueba de Postman o en un caso automatizado.
Esto es lo primero que hay que entender, y lo que más se malinterpreta: un JWT no oculta nada. Sus tres partes van separadas por puntos y codificadas en base64url, que no es cifrado: es una forma de escribir datos con caracteres seguros para una URL. Cualquiera que tenga el token puede leer su contenido:
const token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJyb2wiOiJhZG1pbiJ9.xxx";
// Leer el payload sin tener la clave, en una línea:
JSON.parse(atob(token.split(".")[1]));
// { sub: "123", rol: "admin" }
La consecuencia práctica es directa: nunca metas datos sensibles en el payload. Ni contraseñas, ni números de documento, ni datos de salud, ni nada que no quieras que vea quien intercepte el token o quien lo encuentre guardado en el navegador. La firma garantiza que el contenido no se ha modificado, no que sea secreto.
| Parte | Qué lleva | Ejemplo descodificado |
|---|---|---|
| Cabecera | El algoritmo y el tipo | {"alg":"HS256","typ":"JWT"} |
| Payload | Los datos, las claims | {"sub":"123","exp":1789...} |
| Firma | El resultado de firmar las dos primeras con la clave | 4f2Nc... |
Las claims con nombre reservado son las que tu librería interpreta sola, y conviene
conocerlas: sub es el sujeto —normalmente el identificador de usuario—,
iat el momento de emisión, exp el de expiración, nbf el
momento desde el que el token es válido, iss quién lo emitió y aud
para quién es. Las tres de tiempo van en segundos desde 1970, no en
milisegundos: es un error clásico que produce tokens con fecha de expiración en el año 56000.
El ataque más obvio: alguien coge un token válido, edita el payload para poner
"rol":"admin", y lo reenvía. La firma ya no cuadra, y un backend correcto lo
rechaza. Pero un backend que descodifica sin verificar —usando
jwt.decode() en lugar de jwt.verify(), un error muy común— le
concede permisos de administrador.
Esta herramienta genera exactamente ese token: elige «firma rota» y tendrás un JWT con estructura perfecta, payload legible y firma inválida. Si tu API lo acepta, has encontrado un fallo de seguridad grave.
La especificación admite "alg":"none", es decir, un token sin
firma. La idea era permitir tokens ya protegidos por otro medio, pero varias
librerías antiguas lo aceptaban por defecto: bastaba poner ese algoritmo y borrar la firma para
que el token colara. Tu backend debe declarar qué algoritmos acepta y
rechazar el resto, incluido none.
// MAL: acepta lo que diga la cabecera del propio token
jwt.verify(token, clave);
// BIEN: tú decides el algoritmo, no el atacante
jwt.verify(token, clave, { algorithms: ["HS256"] });
Hay una variante más sutil: si tu servidor acepta HS256 y RS256 a la vez, un atacante puede tomar tu clave pública —que es pública— y usarla como clave secreta de HS256. La defensa es la misma: fijar el algoritmo esperado.
{"rol":"admin"} y comprueba que el permiso se decide en el servidor y no confiando en lo que diga el token.exp. Un token sin expiración es válido para siempre. ¿Tu backend lo acepta? Debería tener una política.La firma se calcula en tu navegador con la API de criptografía del propio navegador. No hay servidor: ni la clave secreta que escribes, ni el payload, ni el token resultante se envían a ninguna parte. Puedes comprobarlo en la pestaña Red de las herramientas de desarrollo: al pulsar «generar» no aparece ninguna petición del generador. Las que veas serán del bloque de publicidad, que es un componente independiente y no tiene acceso a lo que escribes.
Dicho esto, y por sentido común: no uses aquí la clave de producción. No porque este sitio la vaya a ver —no puede—, sino porque pegar una clave de producción en cualquier página web es un hábito que tarde o temprano sale mal. Para probar, cualquier cadena sirve.
Preguntas frecuentes
No. La firma se calcula en tu navegador con la API de criptografía nativa, y no hay servidor al que enviar nada. Aun así, no uses la clave de producción: es una buena costumbre no pegarla nunca en una web, sea cual sea.
No. Está firmado, que es distinto. El payload va en base64url y cualquiera puede leerlo con una línea de código. La firma garantiza que nadie lo ha modificado, no que sea secreto: nunca pongas datos sensibles dentro.
Para comprobar que tu backend lo rechaza. Es el fallo de seguridad más frecuente con JWT: descodificar el token sin verificar la firma, y entonces cualquiera puede editarse el payload y darse permisos de administrador.
La especificación admite «alg»: «none», un token sin firma. Varias librerías antiguas lo aceptaban por defecto, así que bastaba con poner ese algoritmo y borrar la firma. La defensa es declarar en el servidor qué algoritmos aceptas y rechazar el resto.
Sí, cualquier JSON válido. Se codifica tal cual dentro del token. También puedes activar las fechas automáticas para que añada iat y exp, con expiración en el futuro o en el pasado.
No. El token está firmado con la clave que tú escribas, no con la del servicio, así que cualquier backend real lo rechazará. Es un token para probar tu propio software.
Sigue probando