Mensagem de erro
jwt signature is required
jsonwebtoken (Node.js) — JsonWebTokenError from jwt.verify()
O que significa
O terceiro segmento do token está vazio — é um JWT não protegido (`alg: "none"`) ou um token assinado cuja assinatura foi cortada —, mas você chamou `verify()` com uma chave, então a assinatura é obrigatória. O jsonwebtoken recusa o token em vez de aceitar claims que ninguém assinou. Se tokens assim chegam à sua API vindos de fora, alguém pode estar testando a clássica falha “alg none”.
Por que acontece
Um token não protegido com alg “none”
comumA RFC 7519 permite JWTs sem assinatura em contextos em que a integridade é garantida de outra forma; uma API nunca é um desses contextos. Um token como `eyJhbGciOiJub25lIn0.eyJzdWIiOiJhZG1pbiJ9.` alega qualquer identidade que quiser.
Tokens montados à mão em testes ou ferramentas
ocasionalFixtures montadas com a codificação base64 de um cabeçalho e de um payload, ou tokens gerados por ferramentas de depuração com a assinatura desativada, têm a assinatura vazia.
A assinatura foi removida no caminho
ocasionalQuando um filtro que mascara dados nos logs, um limite de tamanho de URL ou uma coluna de armazenamento corta o token logo após o segundo ponto, sobram um cabeçalho e um payload de aparência válida, sem nada para verificar.
Como corrigir
- 1.
Manter a rejeição e a lista de algoritmos permitidos
Verifique com uma lista explícita em `algorithms` que inclua apenas o que seu emissor usa. Registre em log a origem da requisição se chegarem tokens sem assinatura vindos de fora; não adicione um caminho de código que os aceite.
js // Always pass an explicit allow-list; "none" must never be in it. const claims = jwt.verify(token, publicKey, { algorithms: ["ES256"] }); - 2.
Assinar os tokens de teste com uma chave descartável
Gere um par de chaves na preparação dos testes e assine as fixtures com ele, para que os testes percorram o mesmo caminho de verificação que a produção.
js import { generateKeyPairSync } from "node:crypto"; // Test setup: a throwaway key pair, real signatures, same verification path as production. const { privateKey, publicKey } = generateKeyPairSync("ec", { namedCurve: "P-256" }); const token = jwt.sign({ sub: "test-user" }, privateKey, { algorithm: "ES256", expiresIn: "5m" });