Mensaje de error
jwt malformed
Qué significa
La función jwt.verify() de jsonwebtoken ni siquiera pudo analizar el token: la cadena no se divide en exactamente tres segmentos separados por puntos. La firma no se llegó a comprobar: la cadena que pasas no tiene la estructura de un JWT. (Una cadena que sí tiene tres segmentos, pero cuyo encabezado no es JSON en base64url, falla un paso después, con «invalid token».)
Por qué ocurre
El encabezado Authorization se dividió mal
frecuenteEl valor del encabezado Authorization es «Bearer eyJ...», y el código se quedó con la mitad equivocada: auth.split(" ")[0] le pasa a jwt.verify() el propio esquema «Bearer», que no tiene ningún punto. Pasar la cadena «Bearer eyJhbGci...» entera falla de otra manera: sigue dividiéndose en tres segmentos, así que jsonwebtoken informa de «invalid token» cuando el primero no se puede decodificar.
La variable equivocada llegó a verify()
frecuenteUna cadena que no es un token acabó donde debería estar el token: «undefined» o «null» al interpolar un valor ausente (un cliente que envía «Bearer null» porque no había nada guardado, un req.headers.authorisation mal escrito, una cookie que falta), «[object Object]» al convertir en cadena la carga útil decodificada en lugar de pasar el token en bruto, o un ID de usuario. Un undefined, un null o una cadena vacía de verdad se detectan una comprobación antes, con «jwt must be provided».
El token se truncó al guardarlo o al transmitirlo
ocasionalUna columna VARCHAR(255) de la base de datos, el límite de longitud de una línea de registro o un copiar y pegar que perdió el final pueden cortar el token de forma que sobrevivan menos de tres segmentos. Los tokens ES256 ocupan unos 200 caracteres o más; los tokens RS256 son mucho más largos.
No es un JWT en absoluto
ocasionalAlgunos proveedores de OAuth emiten tokens de acceso opacos (cadenas aleatorias) que no son JWT. Pasar a jwt.verify() un access_token opaco de Google/GitHub falla aquí: solo se garantiza que el id_token (OpenID Connect) sea un JWT.
Cómo solucionarlo
- 1.
Quitar el prefijo del esquema antes de verificar
Toma solo la parte del token del encabezado Authorization y contempla el caso de que falte el encabezado, para fallar con un 401 claro en lugar de con «jwt malformed».
js const auth = req.headers.authorization ?? ""; const [scheme, token] = auth.split(" "); if (scheme !== "Bearer" || !token) { return res.status(401).json({ error: "missing bearer token" }); } jwt.verify(token, publicKey, { algorithms: ["ES256"] }); - 2.
Registrar el valor en bruto y contar sus segmentos
Una sola línea de registro te dice si se trata de un prefijo, de un truncamiento o de la variable equivocada. Un JWS tiene exactamente 3 segmentos; un JWE, 5; cualquier otra cosa no es un token.
js console.log(JSON.stringify(token).slice(0, 80)); console.log("segments:", String(token).split(".").length); // must be 3 - 3.
Comprobar qué contiene realmente el token
Pega la cadena en el depurador de JWT de abajo: decodifica localmente el encabezado y los claims (declaraciones) y te dice exactamente qué segmento está roto, o que la cadena no es un JWT en absoluto.