Mensagem de erro
jwt malformed
O que significa
O jwt.verify() do jsonwebtoken não conseguiu nem analisar o token: a string não se divide em exatamente três segmentos separados por pontos. A assinatura nem chegou a ser verificada — a string que você passou não tem a estrutura de um JWT. (Uma string que tem, sim, três segmentos, mas cujo cabeçalho não é JSON em base64url falha uma etapa depois, com “invalid token”.)
Por que acontece
O cabeçalho Authorization foi dividido do jeito errado
comumO valor do cabeçalho Authorization é “Bearer eyJ...”, e o código ficou com a metade errada: auth.split(" ")[0] entrega ao jwt.verify() o próprio esquema “Bearer”, que não tem ponto nenhum. Passar a string inteira “Bearer eyJhbGci...” falha de outro jeito — ela ainda se divide em três segmentos, então o jsonwebtoken informa “invalid token” quando o primeiro não pode ser decodificado.
A variável errada chegou ao verify()
comumUma string que não é um token foi parar onde o token deveria estar: “undefined” ou “null” vindos da interpolação de um valor ausente (um cliente que envia “Bearer null” porque nada foi armazenado, um req.headers.authorisation com erro de digitação, um cookie ausente), “[object Object]” por converter em string o payload decodificado em vez de passar o token bruto, ou um ID de usuário. Já os valores undefined e null de verdade, assim como uma string vazia, são barrados uma verificação antes, com “jwt must be provided”.
O token foi truncado no armazenamento ou no trânsito
ocasionalUma coluna VARCHAR(255) no banco de dados, um limite de tamanho de linha de log ou um copiar e colar que perdeu o final podem cortar o token, de modo que sobrem menos de três segmentos. Tokens ES256 têm cerca de 200 caracteres ou mais; tokens RS256 são bem mais longos.
Não é um JWT de forma alguma
ocasionalAlguns provedores OAuth emitem tokens de acesso opacos (strings aleatórias) que não são JWTs. Passar um access_token opaco do Google/GitHub para o jwt.verify() falha aqui — só o id_token (OpenID Connect) tem garantia de ser um JWT.
Como corrigir
- 1.
Remover o prefixo do esquema antes de verificar
Pegue só a parte do token do cabeçalho Authorization e trate o caso de cabeçalho ausente, para falhar com um 401 claro em vez de “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 o valor bruto em log e contar os segmentos
Uma única linha de log mostra se o problema é um prefixo, um truncamento ou a variável errada. Um JWS tem exatamente 3 segmentos; um JWE tem 5; qualquer outra coisa não é um token.
js console.log(JSON.stringify(token).slice(0, 80)); console.log("segments:", String(token).split(".").length); // must be 3 - 3.
Verificar o que o token realmente contém
Cole a string no depurador de JWT abaixo: ele decodifica o cabeçalho e as claims localmente e mostra exatamente qual segmento está quebrado — ou que a string nem é um JWT.