Mensaje de error
jwt must be provided
jsonwebtoken (Node.js) — JsonWebTokenError from jwt.verify()
Qué significa
`jwt.verify()` no recibió ningún token: el primer argumento era `undefined`, `null` o una cadena vacía. jsonwebtoken lo comprueba antes de analizar nada, así que ni la clave ni el formato del token importan todavía. El problema está antes: el código que extrae el token de la solicitud no encontró nada.
Por qué ocurre
El cliente no envió un encabezado Authorization
frecuenteLa solicitud llegó a la ruta sin token: el usuario no había iniciado sesión, el cliente olvidó adjuntar el encabezado o el token caducó en el cliente y se borró. Entonces, un código como `req.headers.authorization.split(" ")[1]` da `undefined`.
El token se lee del lugar equivocado
frecuentePropiedades mal escritas (`authorisation`, `Authorization` en un mapa de encabezados en minúsculas), un encabezado personalizado como `x-access-token` o un parámetro de consulta que el código no lee. Node pasa a minúsculas los nombres de los encabezados entrantes, así que `req.headers.Authorization` siempre es `undefined`.
La cookie de sesión no llegó
ocasionalLas solicitudes entre orígenes omiten las cookies salvo que el cliente establezca `credentials: "include"` y la cookie sea `SameSite=None; Secure`. Sin el middleware cookie-parser, `req.cookies` también está vacío.
El token aún no estaba listo
ocasionalLos frontends que piden datos antes de que el flujo de inicio de sesión guarde el token, o que leen el token del almacenamiento de forma asíncrona, envían las primeras solicitudes con un valor vacío.
Cómo solucionarlo
- 1.
Extraer el token de forma defensiva y responder con 401
Comprueba si falta el token antes de llamar a `verify` y devuelve 401 con un encabezado `WWW-Authenticate: Bearer`. Así, los clientes ven «no autenticado» en lugar de un 500 por un error no capturado.
js function bearerToken(req) { const [scheme, token] = (req.headers.authorization ?? "").split(" "); return scheme?.toLowerCase() === "bearer" && token ? token : null; } app.use((req, res, next) => { const token = bearerToken(req); if (!token) return res.status(401).set("WWW-Authenticate", "Bearer").end(); try { req.user = jwt.verify(token, publicKey, { algorithms: ["ES256"] }); next(); } catch { res.status(401).set("WWW-Authenticate", 'Bearer error="invalid_token"').end(); } }); - 2.
Hacer que el cliente adjunte el token
Confirma en el panel de red del navegador que la solicitud lleva `Authorization: Bearer …` (o la cookie). Si el encabezado se ve en el navegador pero falta en el servidor, lo elimina un proxy intermedio.
js // Browser / Node 18+ fetch: the token must be attached explicitly. await fetch("https://api.example.com/orders", { headers: { Authorization: "Bearer " + accessToken }, }); // Cookies cross origins only with credentials and SameSite=None; Secure. await fetch("https://api.example.com/orders", { credentials: "include" });