Aprende qué es un JWT (JSON Web Token), cómo funcionan sus tres partes, dónde se usan y las recomendaciones de seguridad clave para evitar errores comunes.

Un JWT (JSON Web Token) es una cadena compacta y segura para URLs que representa un conjunto de información (normalmente sobre un usuario o sesión) de forma que puede transmitirse entre sistemas. A menudo lo verás como un valor largo que empieza con algo como eyJ..., enviado en una cabecera HTTP como Authorization: Bearer \u003ctoken\u003e.
Los inicios de sesión tradicionales suelen apoyarse en sesiones en el servidor: después de iniciar sesión, el servidor guarda datos de sesión y entrega al navegador una cookie con el ID de sesión. Cada petición incluye esa cookie y el servidor consulta la sesión.
Con autenticación basada en tokens, el servidor puede evitar mantener estado de sesión para cada petición del usuario. En su lugar, el cliente guarda un token (como un JWT) y lo incluye en las llamadas a la API. Esto es popular para APIs porque:
Matiz importante: “sin estado” no significa “sin comprobaciones en servidor”. Muchos sistemas reales siguen validando tokens contra el estado del usuario, rotación de claves o mecanismos de revocación.
Los JWT suelen llevar pruebas de autenticación (estás autenticado) y pistas básicas de autorización (roles, permisos, scopes), pero tu servidor debe seguir aplicando las reglas de autorización.
Suele usarse JWT como tokens de acceso en:
Un JWT es una cadena compacta formada por tres partes, cada una codificada en base64url y separadas por puntos:
header.payload.signature
Ejemplo (redactado):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNzAwMDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c…
La cabecera describe cómo se creó el token—lo más importante es el algoritmo de firma (p. ej., HS256, RS256/ES256) y el tipo de token.
Campos comunes:
typ: a menudo "JWT" (frecuentemente ignorado en la práctica)alg: el algoritmo de firma usadokid: un identificador de clave para ayudar al verificador a seleccionar la clave correcta durante la rotaciónNota de seguridad: no confíes ciegamente en la cabecera. Aplica una lista de algoritmos permitidos que realmente uses y no aceptes alg: "none".
El payload contiene “claims” (campos) sobre el usuario y el contexto del token: para quién es, quién lo emitió y cuándo expira.
Importante: los JWT no están cifrados por defecto. La codificación Base64URL hace que el token sea seguro para URLs; no oculta los datos. Cualquiera que obtenga el token puede decodificar la cabecera y el payload.
Por eso debes evitar poner secretos (contraseñas, claves de API) o datos personales sensibles en un JWT.
La firma se crea firmando la cabecera + payload con una clave:
La firma proporciona integridad: permite verificar que el token no fue modificado y que fue emitido por un firmante de confianza. No proporciona confidencialidad.
Como un JWT incluye cabecera y payload en cada petición donde se envía, tokens más grandes implican más ancho de banda y sobrecarga. Mantén los claims compactos y prefiere identificadores en lugar de datos voluminosos.
Los claims suelen agruparse en dos categorías: registrados (nombres estandarizados) y personalizados (campos de tu app).
iss (issuer): quién creó el tokensub (subject): a quién se refiere el token (a menudo un ID de usuario)aud (audience): para quién está pensado el token (p. ej., una API específica)exp (expiration time): cuándo debe dejar de aceptarse el tokeniat (issued at): cuándo se creó el tokennbf (not before): no aceptar el token antes de este momentoIncluye solo lo que el servicio receptor realmente necesita para tomar una decisión de autorización.
Buenos ejemplos:
user_id)Evita claims de “conveniencia” que dupliquen muchos datos del perfil. Inflan el token, quedan obsoletos con rapidez y aumentan el impacto si el token se filtra.
Dado que el payload es legible, no almacenes:
Si necesitas información sensible, guárdala en el servidor y pon solo una referencia (como un ID) en el token—o usa un formato de token cifrado (JWE) cuando proceda.
Firmar no es cifrar.
Cuando se emite un JWT, el servidor firma la cabecera y el payload codificados. Cuando el token se presenta más tarde, el servidor recalcula la firma y la compara. Si alguien cambia aunque sea un carácter (p. ej., "role":"user" a "role":"admin"), la verificación falla y el token se rechaza.
JWT es un formato de token. OAuth 2.0 y OpenID Connect (OIDC) son protocolos que describen cómo las apps solicitan, emiten y usan tokens.
OAuth 2.0 trata principalmente sobre autorización: permitir que una app acceda a una API en nombre de un usuario sin compartir la contraseña del usuario.
Los access tokens suelen ser de corta duración (minutos). Duraciones cortas limitan el daño si un token se filtra.
OIDC añade autenticación (quién es el usuario) sobre OAuth 2.0 e introduce un ID token, que normalmente es un JWT.
Regla clave: no uses un ID token para llamar a una API.
Si quieres más contexto sobre flujos prácticos, consulta /blog/jwt-authentication-flow.
Un flujo típico se ve así:
El usuario inicia sesión (email/contraseña, SSO, etc.). Si tiene éxito, el servidor crea un JWT (a menudo un access token) con claims esenciales como el subject y la expiración.
El servidor firma el token y lo devuelve al cliente (app web, móvil u otro servicio).
Para endpoints protegidos, el cliente incluye el JWT en la cabecera Authorization:
Authorization: Bearer \u003cJWT\u003e
Antes de atender la petición, la API normalmente comprueba:
exp (no caducado)iss (emisor esperado)aud (destinado a esta API)Si todas las comprobaciones pasan, la API trata al usuario como autenticado y aplica reglas de autorización (p. ej., permisos a nivel de registro).
Como los relojes de los sistemas derivan, muchos sistemas permiten un pequeño desajuste de reloj al validar claims basados en tiempo como exp (y a veces nbf). Mantén el desajuste pequeño para no alargar la validez del token más de lo previsto.
Las opciones de almacenamiento cambian qué atacantes pueden robar y con qué facilidad pueden reproducir un token.
Almacenamiento en memoria (a menudo recomendado para SPAs) mantiene el access token en el estado JS. Se borra al recargar y reduce el riesgo de “robarlo después”, pero un bug XSS aún puede leerlo mientras la página está activa. Combínalo con tokens de corta vida y un flujo de refresh.
localStorage/sessionStorage son fáciles pero arriesgados: cualquier XSS puede exfiltrar tokens del almacenamiento web. Si los usas, trata la prevención de XSS como algo no negociable (CSP, escape de salida, higiene de dependencias) y mantén tokens de corta duración.
Cookies seguras (a menudo el valor por defecto más seguro para web) almacenan tokens en una cookie HttpOnly para que JavaScript no pueda leerlos—reduciendo el impacto del robo por XSS. El intercambio es el riesgo de CSRF, ya que los navegadores adjuntan cookies automáticamente.
Si usas cookies, configura:
HttpOnlySecure (solo HTTPS)SameSite=Lax o SameSite=Strict (algunos flujos cross-site pueden necesitar SameSite=None; Secure)También considera tokens CSRF para peticiones que cambian estado.
En iOS/Android, guarda tokens en el almacenamiento seguro de la plataforma (Keychain / Keystore respaldado). Evita archivos planos o preferencias. Si tu modelo de amenaza incluye dispositivos rooteados/jailbreakeados, asume extracción posible y confía en tokens de corta vida y controles server-side.
Limita lo que un token puede hacer: usa scopes/claims mínimos, mantén access tokens de corta duración y evita incrustar datos sensibles.
Los JWT son convenientes, pero muchos incidentes provienen de errores previsibles. Trata un JWT como efectivo: quien lo obtiene, a menudo puede gastarlo.
Si un token dura días o semanas, una filtración da al atacante toda esa ventana.
Prefiere access tokens de corta duración (minutos) y renuévalos mediante un mecanismo más seguro. Si necesitas “recordarme”, hazlo con refresh tokens y controles server-side.
Las firmas válidas no bastan. Verifica iss y aud, y valida claims temporales como exp y nbf.
Decodificar no es verificar. Verifica siempre la firma en el servidor y aplica permisos en el servidor.
Evita poner JWTs en parámetros de consulta. Pueden acabar en el historial del navegador, logs del servidor, herramientas de analítica y cabeceras referer.
Usa Authorization: Bearer ... en su lugar.
Asume que claves y tokens pueden filtrarse. Rota claves de firma, usa kid para soportar rotación suave y ten una estrategia de revocación (expiraciones cortas + capacidad para desactivar cuentas/sesiones). Para guías sobre almacenamiento, consulta /blog/where-to-store-jwts-safely.
Los JWT son útiles, pero no siempre son la mejor opción. La pregunta real es si te beneficia un token autocontenido que pueda verificarse sin consultar la base de datos en cada petición.
Para aplicaciones renderizadas en servidor donde la invalidación sencilla es importante, sesiones server-side con cookies HttpOnly suelen ser la opción más simple y segura.
Elige JWT si necesitas verificación sin estado entre servicios y puedes mantener tokens de corta duración.
Evita JWT si necesitas revocación instantánea, piensas almacenar datos sensibles en el token, o puedes usar cookies de sesión sin fricciones.
Verifica usando la clave correcta y el algoritmo esperado. Rechaza firmas inválidas—sin excepciones.
exp (expiración)Asegúrate de que el token no haya expirado.
nbf (not before)Si está presente, comprueba que el token no se esté usando antes de tiempo.
aud (audience)Confirma que el token estaba destinado a tu API/servicio.
iss (issuer)Confirma que el token vino del emisor esperado.
Valida el formato del token, aplica un tamaño máximo y rechaza tipos de claim inesperados para reducir bugs en casos límite.
HS256 (clave simétrica): una secret compartida firma y verifica.
RS256 / ES256 (claves asimétricas): la clave privada firma; la pública verifica.
Regla práctica: si más de un sistema independiente necesita verificar tokens (o no confías completamente en cada verificador), prefiere RS256/ES256.
iss, aud y un ID de usuario solo si la política lo permite).¿Está cifrado un JWT?
No por defecto. La mayoría de los JWT son firmados, no cifrados, lo que significa que su contenido puede leerse si alguien tiene el token. Usa JWE o mantén datos sensibles fuera de los JWT.
¿Puedo revocar un JWT?
No fácilmente si dependes solo de access tokens autocontenidos. Enfoques comunes: tokens de corta vida, listas de denegación para eventos de alto riesgo, o refresh tokens con rotación.
¿Cuánto debería durar exp?
Lo más corto que permita tu UX y arquitectura. Muchas APIs usan minutos para access tokens, combinados con refresh tokens para sesiones más largas.
Si implementas autenticación JWT en una API nueva o SPA, mucho del trabajo es repetitivo: configurar middleware, validar iss/aud/exp, establecer flags de cookie y evitar que el manejo de tokens aparezca en logs.
Con Koder.ai, puedes prototipar una app web (React), servicios backend (Go + PostgreSQL) o una app móvil Flutter mediante un flujo guiado por chat—iterar en un modo de planificación, usar snapshots y rollback mientras afinás la seguridad, y exportar el código cuando estés listo. Es una forma práctica de acelerar la construcción de flujos de autenticación basados en JWT manteniendo control sobre la lógica de verificación, estrategia de rotación de claves y ajustes de despliegue (incluidos dominios personalizados).
Un JWT (JSON Web Token) es una cadena compacta y segura para URL que transporta claims (campos de datos) y puede ser verificada por un servidor. Se envía comúnmente en peticiones API mediante:
Authorization: Bearer <token>La idea clave: el servidor puede validar la integridad del token (vía su firma) sin necesitar un registro de sesión por usuario en cada petición.
La autenticación por sesión normalmente guarda estado en el servidor (un registro de sesión indexado por una cookie/ID de sesión). Con autenticación basada en JWT, el cliente presenta un token firmado en cada petición y la API lo valida.
Los JWT son populares para APIs y arquitecturas con varios servicios porque la verificación puede hacerse localmente, reduciendo la necesidad de almacenamiento de sesión compartido.
“Sin estado” aún suele incluir comprobaciones en servidor como listas de revocación, verificación del estado del usuario o rotación de claves.
Un JWT son tres partes codificadas en Base64URL separadas por puntos:
header.payload.signatureLa cabecera describe cómo se firmó, el payload contiene claims (como sub, exp, aud) y la firma permite al servidor detectar manipulaciones.
No. Los JWT estándar suelen estar firmados, no cifrados.
Si necesitas confidencialidad, considera JWE (tokens cifrados) o deja los datos sensibles en el servidor y solo almacena un identificador en el JWT.
La firma permite verificar que el token no fue alterado y que lo creó quien posee la clave de firma.
No garantiza:
expTrata el token como una credencial: si se filtra, a menudo puede reutilizarse hasta que expire.
alg indica el algoritmo usado (p. ej., HS256 vs RS256). kid es un identificador de clave que ayuda a elegir la clave de verificación durante la rotación.
Reglas de seguridad:
Empieza con los claims registrados estándar y mantén los personalizados al mínimo.
Claims registrados comunes:
JWT es un formato de token; OAuth 2.0 y OpenID Connect son protocolos.
Mapeo típico:
Para apps web, las opciones comunes son:
localStorage/sessionStorage: conveniente, pero cualquier XSS puede exfiltrar tokens.Como mínimo, valida:
exp (no expirado)iss (emisor esperado)aud (destinado a tu API)nbf (si está presente)Añade defensas prácticas:
alg.alg: "none".kid no confiable produzca comportamientos de búsqueda de clave inseguros.iss (issuer) — quién creó el tokensub (subject) — a quién se refiere el token / id de usuarioaud (audience) — para quién está pensado el tokenexp (expiration) — cuándo expiraiat (issued at) — cuándo se emitiónbf (not before) — no aceptar antes de este tiempoEvita poner secretos o datos personales sensibles en el payload, ya que son legibles si el token se expone.
Importante: no uses un ID token para llamar a una API solo porque “parece” un JWT de acceso.
SameSite + tokens CSRF para peticiones que cambian estado).Sea cual sea la opción, mantén los access tokens cortos y limita privilegios.