Seguridad

Generador de JWT de Prueba

Generá JWTs de test con claims realistas para tus ambientes locales. Headers configurables, payloads edge-case y escenarios de expiración sin contaminar tus secrets de producción.

Instantáneo🔒En tu navegadorSin registro
En vivo
    Ver como texto

    Por qué nunca deberías usar JWTs reales en desarrollo local

    El error más común: copiar un JWT de producción, pegarlo en Postman y usarlo para testear localmente. Problema: ese token tiene claims reales, firma válida y expone tu secret de firma si alguien hookea tu tráfico local. Un dev de una fintech compartió sin querer un token real en un issue público de GitHub; en 40 minutos tenían requests fraudulentos golpeando el API porque el token incluía scopes de admin y el iss apuntaba a producción.

    Los tokens de test deben tener issuers ficticios, subs no rastreables a usuarios reales y expirations cortas. Si tu JWT de dev dice "sub": "admin@company.com", estás filtrando información de negocio. Mejor: "sub": "test-user-001". Y el iss debe ser algo como https://local.dev, nunca tu dominio real. Esto previene que un token de test accidentalmente válido llegue a producción si hay bug de routing.

    Otro antipatrón: JWTs de test sin expiración. Parece conveniente ('nunca tengo que regenerarlo'), pero rompe tu capacidad de testear flujos de refresh y te acostumbra a ignorar exp. Los mejores equipos generan tokens con exp relativo: 'ahora + 1 hora' en dev, 'ahora + 5 minutos' para testear edge cases de expiración. Automatizá la generación en tu seed script o docker-compose, nunca hardcodees tokens en el repo.

    Claims personalizados que rompen en producción si no los testeas

    Los standard claims (iss, sub, aud, exp) son solo el principio. La mayoría de los bugs de JWT vienen de custom claims mal validados. Ejemplo clásico: tu API espera "roles": ["admin", "user"] (array), pero tu IdP externo manda "roles": "admin" (string) cuando hay un solo rol. Tu código hace roles.includes('admin') y explota en producción.

    Generá tokens de test con todas las variantes de shape que podés recibir: roles como array vacío, roles como string, roles ausente, roles con valores inesperados. Lo mismo para aud: puede ser string único o array, y muchas libs JWT validan diferente según el tipo. Un equipo de auth perdió medio día debugueando por qué Auth0 mandaba "aud": ["api", "dashboard"] (array) pero su mock local tenía "aud": "api" (string) — el código de validación solo esperaba uno.

    Testing crítico: nested claims y tipos no-string. Si tenés "metadata": {"plan": "pro"}, validá que tu parser maneja objetos nested sin romper. Y claims como "is_admin": true (boolean) vs "is_admin": "true" (string) — JavaScript hace type coercion silenciosa que puede pasar tests pero fallar en validaciones estrictas de otros lenguajes. Generá tokens con "active": 1, "active": "1", "active": true y verificá que tu backend maneja los tres o rechaza los incorrectos explícitamente.

    Escenarios edge-case que tu suite de tests está ignorando

    El 90% de los tests de JWT verifican el happy path: token válido, no expirado, firma correcta. Los bugs reales vienen del 10% restante. Tokens sin exp: ¿tu API los rechaza o los acepta como eternos? Según RFC 7519 exp es opcional, pero muchos sistemas asumen que siempre está presente. Tokens con nbf (not before) en el futuro: ¿validás que el token todavía no es válido? Un sistema de CI generaba tokens con nbf 5 minutos en el futuro para clock skew, pero el API no verificaba nbf — aceptaba tokens que todavía no deberían funcionar.

    Casos de seguridad críticos: header con "alg": "none". Muchas libs JWT viejas aceptaban tokens sin firma si el header decía 'none', permitiendo que cualquiera forge tokens. Tu código debe rechazar explícitamente alg: none o tener whitelist de algoritmos permitidos. Otro: aud claim ausente o mismatch. Si tu API espera "aud": "my-api" pero recibe un token con "aud": "other-api", ¿lo rechaza o lo acepta? Ese validation gap permite ataques de token substitution entre servicios.

    Edge case de parsing: duplicate claims. JSON permite (técnicamente) {"exp": 100, "exp": 200}. Algunos parsers toman el primero, otros el último, otros explotan. Generá un token así y verificá que tu stack lo rechaza o maneja consistentemente. Y claims con valores extremos: exp con timestamp negativo, iat en el futuro lejano, strings gigantes (1MB en un claim para DoS), null bytes, SQL injection en sub. Si tu token de test solo tiene 'user123', nunca vas a cachear que alguien puede mandar 'user123\'; DROP TABLE--'.

    Headers JWT que cambian el comportamiento de validación

    La mayoría de los devs solo conoce {"alg": "HS256", "typ": "JWT"}, pero el header define cómo tu sistema debe validar el token. kid (key ID): identifica qué clave usar cuando rotás secrets. Si tu sistema soporta múltiples claves activas (para rotación sin downtime), debe extraer kid del header y buscar la clave correcta. Un token con kid inexistente debe ser rechazado, no validado contra la clave default. Ese fue el vector de un CVE en un OAuth provider popular.

    Algoritmos críticos: RS256 vs HS256. RS256 usa asimetría (public/private key), HS256 usa clave simétrica. Si tu código está configurado para RS256 pero recibe un token HS256, algunos parsers toman la clave pública (que es... pública) como secret HMAC y validan incorrectamente. Esto permitía forging de tokens en varias implementaciones. Solución: whitelist explícita de algoritmos permitidos, nunca confíes en el alg del header sin verificar contra tu configuración.

    cty (content type): si es "JWT", indica nested JWT (un JWT dentro de otro JWT). Tu parser debe deserializar recursivamente. Y crit (critical): lista claims que DEBEN ser entendidos para validar el token. Si tu sistema no implementa un claim listado en crit, debe rechazar el token. Esto previene downgrade attacks donde un atacante remueve validaciones esperando que sean silenciosamente ignoradas. Generá tokens de test con "crit": ["exp"] y verificá que tu sistema efectivamente valida exp o rechaza el token.

    Preguntas frecuentes

    ¿Puedo usar estos JWTs de test en ambientes compartidos de staging?

    No sin coordinación. Si el staging usa el mismo issuer y secret que prod, un token de test podría validar contra recursos reales. Mejor: staging debe tener issuer único (ej 'https://staging.api.com') y secrets diferentes.

    ¿Qué algoritmo de firma debería usar para tokens de test local?

    HS256 es suficiente para local/dev porque no sale de tu máquina. Para staging compartido, usá RS256 (asimétrico) para simular el comportamiento de producción donde solo el auth server tiene la private key.

    ¿Cómo genero el 'exp' timestamp correcto para que el token dure X horas?

    exp es Unix timestamp (segundos desde 1970). En JS: Math.floor(Date.now()/1000) + (horas * 3600). En Python: int(time.time()) + (horas * 3600). Herramientas como jwt.io tienen helpers para esto.

    Mi API rechaza los tokens generados aquí, ¿qué puede estar mal?

    Tres causas comunes: 1) secret de firma incorrecto (el token de test debe estar firmado con el mismo secret de tu ambiente), 2) validación de 'aud' o 'iss' muy estricta, 3) 'exp' ya pasado (regenerá con fecha futura).

    ¿Te sirvió este generador?