Cómo solucionar "JWT expired" y errores comunes de JSON Web Token: Guía Completa
Los JSON Web Tokens (JWT) son el estándar de la industria para transmitir información de forma segura entre partes como un objeto JSON. Se utilizan ampliamente para la autenticación y autorización en aplicaciones web y móviles modernas. Sin embargo, debido a que están firmados criptográficamente y a menudo tienen reglas de expiración estrictas, pueden ser una fuente importante de dolores de cabeza al depurar.
En esta guía, desglosaremos los errores de JWT más comunes, explicaremos por qué ocurren y te mostraremos cómo solucionarlos.
1. Mensajes de error comunes de JWT
Dependiendo de la biblioteca que utilices (como jsonwebtoken en Node.js), te encontrarás con estos nombres de error comunes:
TokenExpiredError: El token es válido pero ha superado su tiempo de expiración.JsonWebTokenError: invalid signature: La firma del token no coincide con el secreto/llave proporcionada.JsonWebTokenError: jwt malformed: La cadena proporcionada no es una estructura JWT válida.JsonWebTokenError: jwt signature is required: Se proporcionó un token sin la sección de firma.JsonWebTokenError: jwt invalid audience: El reclamoauden el token no coincide con el valor esperado.
2. Principales causas y soluciones
2.1 "TokenExpiredError" (JWT expired)
Todo JWT seguro debe tener un reclamo exp (expiración). Una vez que el tiempo actual supera este valor, el token deja de ser válido.
El síntoma:
Los usuarios cierran la sesión repentinamente o las solicitudes de API comienzan a devolver errores 401 Unauthorized con el mensaje jwt expired.
La solución:
- Refresh Tokens: Implementa una estrategia de "Refresh Token" para que los usuarios no tengan que iniciar sesión manualmente cada vez que expire un token de acceso.
- Sincronización de reloj: Asegúrate de que el reloj de tu servidor esté sincronizado mediante NTP. Incluso unos pocos segundos de diferencia pueden causar problemas.
- Verifica
iatynbf: Asegúrate de que los reclamos "emitido en" (iat) y "no antes de" (nbf) también sean correctos.
2.2 "invalid signature" (invalid JWT signature)
Un JWT consta de tres partes: Encabezado (Header), Carga útil (Payload) y Firma (Signature). La firma se crea mediante el hashing del encabezado y la carga útil con una clave secreta. Si cambia incluso un solo carácter en la carga útil, o si se utiliza la clave secreta incorrecta, la firma se vuelve inválida.
La causa:
- Uso del
secretopublic keyincorrecto para verificar el token. - Un desajuste entre el algoritmo utilizado para firmar (ej. HS256) y verificar (ej. RS256).
- El token fue manipulado o se corrompió durante la transmisión.
La solución:
- Verifica dos veces tus variables de entorno para la clave secreta.
- Verifica que el encabezado
algen el JWT coincida con el algoritmo que estás utilizando para la verificación.
2.3 "jwt malformed" o "jwt decode failed"
Un JWT válido debe tener tres partes separadas por puntos (header.payload.signature). Si falta alguna parte o si la cadena no es Base64URL válida, se considera malformado.
La causa:
- Pasar un prefijo "Bearer " directamente a la biblioteca (ej.
atob("Bearer <token>")). - Copiar y pegar un token parcial.
- Espacios en blanco adicionales o caracteres ocultos en la cadena del token.
La solución:
Asegúrate de eliminar el prefijo Bearer antes de pasarlo a tu decodificador.
const token = authHeader.split(' ')[1]; // Extraer token de "Bearer <token>"
2.4 "jwt invalid audience" o "jwt invalid issuer"
Estos errores ocurren cuando los reclamos aud (audiencia) o iss (emisor) en la carga útil no coinciden con los valores que tu servidor espera.
La solución: Asegúrate de que la configuración en tu servidor de autenticación (ej. Auth0, Firebase o el tuyo propio) coincida con las opciones de verificación en el código de tu aplicación.
3. Solución de problemas avanzada
3.1 Inspección de la carga útil
Si obtienes un error de firma, el primer paso es inspeccionar la carga útil para ver si contiene los datos que esperas. No necesitas la clave secreta para decodificar y leer la carga útil (ya que solo está codificada en Base64).
3.2 Ataques de confusión de algoritmo (Algorithm Confusion Attacks)
Asegúrate de que tu biblioteca esté configurada para permitir solo los algoritmos específicos que esperas. Algunas bibliotecas más antiguas eran vulnerables a un ataque donde un atacante podía cambiar el encabezado a alg: none, eludiendo la seguridad. Las bibliotecas modernas han corregido esto en su mayoría, pero siempre define explícitamente tus algoritmos permitidos.
jwt.verify(token, secret, { algorithms: ['HS256'] });
4. Prevención y mejores prácticas
- Tokens de acceso de corta duración: Mantén los tokens de acceso con una vida corta (ej. 15 minutos) y usa tokens de actualización para sesiones más largas.
- Secretos seguros: Nunca codifiques tu secreto JWT en el código. Usa variables de entorno y rótalas periódicamente.
- Valida cada solicitud: Nunca confíes en un JWT sin verificar su firma en el lado del servidor.
- Usa HTTPS: Transmite siempre los tokens a través de HTTPS para evitar ataques de interceptación "Man-in-the-Middle".
5. FAQ: Preguntas frecuentes
P: ¿Puedo leer los datos dentro de un JWT sin el secreto?
R: Sí. El encabezado y la carga útil solo están codificados en Base64URL, no cifrados. Cualquiera que tenga el token puede leer los datos. Nunca pongas información sensible como contraseñas o números de tarjetas de crédito en la carga útil de un JWT.
P: ¿Cuál es la diferencia entre HS256 y RS256?
R: HS256 utiliza una única clave secreta tanto para firmar como para verificar (simétrico). RS256 utiliza una llave privada para firmar y una llave pública para verificar (asimétrico), lo cual es más seguro para sistemas distribuidos.
P: ¿Cómo manejo un error "jwt expired" en el frontend?
R: Captura el error 401 en tu interceptor de API. Si el error es "jwt expired", intenta llamar a tu endpoint de "refresh token". Si eso falla, redirige al usuario a la página de inicio de sesión.
6. Herramienta de comprobación rápida
¿Tienes problemas con un token específico? Usa nuestro Decodificador y Depurador de JWT. Te permite:
- Decodificar instantáneamente cualquier JWT para ver su Encabezado y Carga útil.
- Verificar el estado de expiración y reclamos como
iat,expynbf. - Identificar tokens malformados (malformed tokens) y problemas de codificación.
- Validar firmas (si proporcionas tu clave secreta localmente).
Errores relacionados
- Cómo solucionar errores de 'Unexpected token in JSON'
- Cómo corregir errores de 'invalid base64 string'
- Cómo solucionar errores de 'invalid regular expression'