Por que o seu JWT foi rejeitado

Decodificar é fácil. O que ninguém te diz é qual claim reprovou — e se o problema é o token, o relógio ou a chave.

Roda no seu navegador · nada é enviado para servidor

Token é credencial. Enquanto ele vale, quem tiver o texto entra como você. Esta página faz tudo no seu navegador e nunca envia o token para lugar nenhum — e por isso mesmo ela não pede a sua chave secreta: sem a chave não dá para conferir a assinatura, e essa é uma limitação de propósito. Se o token for de produção, revogue depois de depurar.

Cole o token

As seis razões pelas quais um token válido é recusado

Repare no “válido”: o token está bem formado, você consegue decodificar, e mesmo assim a API devolve 401. Essas são as causas, na ordem em que aparecem na vida real.

1. exp — expirou

A campeã, e a mais fácil de confirmar. exp é um horário em segundos desde 1970 (não milissegundos — errar isso é clássico em JavaScript, onde Date.now() devolve milissegundos). Se o número for treze dígitos em vez de dez, alguém esqueceu de dividir por mil e o token “expira” daqui a 50 mil anos.

2. nbf — ainda não vale

Not before. O token existe, mas só passa a valer no futuro. Quando isso aparece em produção, quase sempre não é o token: é o relógio da máquina que emitiu estar adiantado em relação ao de quem valida.

3. Relógio fora de sincronia

Este é o que faz gente perder o dia. O token acabou de ser emitido e a API diz que já expirou — porque os dois servidores discordam em alguns segundos. O sintoma denuncia: falha intermitente, mais frequente em tokens de vida curta.

O conserto não é emitir outro token, é aceitar uma folga na validação — e sincronizar o relógio das máquinas:

// jsonwebtoken (Node)
jwt.verify(token, chave, { clockTolerance: 30 })   // segundos

// jose
await jwtVerify(token, chave, { clockTolerance: '30s' })
Tolerância existe para absorver desvio de relógio, não para estender sessão. Trinta segundos resolve o mundo real; minutos viram brecha.

4. aud ou iss não batem

O token é legítimo, só que não é para você. aud diz para qual serviço ele foi emitido e iss diz quem emitiu. Um token do ambiente de homologação chegando na API de produção falha exatamente assim.

Detalhe que morde: aud pode ser string ou lista. Validador que compara com === quebra quando vem lista.

5. O algoritmo não é o que a API espera

Aqui mora um problema de segurança, não só de configuração. Se o verificador aceita o algoritmo que o token declara, um atacante troca RS256 por HS256 e assina usando a chave pública — que é pública — como se fosse segredo compartilhado. Pior: alg: none pede para o verificador não conferir nada.

Por isso todo verificador sério exige que você diga o algoritmo esperado:

jwt.verify(token, chavePublica, { algorithms: ['RS256'] })

Se a sua API recusa com “invalid algorithm”, ela está fazendo o certo — o lado errado é quem emitiu.

6. A chave — kid, rotação e JWKS

Quando as claims passam e a rejeição continua, sobrou a assinatura. O caminho mais comum não é chave errada, é chave certa que não foi encontrada: o header traz um kid, o verificador procura essa chave no JWKS do emissor e não acha, porque houve rotação e o cache local está velho.

# o que o verificador deveria enxergar
curl -s https://auth.exemplo.com/.well-known/jwks.json | jq '.keys[].kid'

Se o kid do seu token não estiver nessa lista, o problema é cache ou emissor errado — não o token.

Como saber que a rejeição é de assinatura

Por eliminação, e é por isso que esta página confere as claims uma a uma. Se exp, nbf, aud, iss e o algoritmo estão todos certos e a API continua devolvendo 401, restam três hipóteses, nesta ordem:

Chave errada — o segredo da API não é o mesmo que assinou. Acontece muito entre ambientes.
Chave não encontrada — o kid não está no JWKS atual.
Token adulterado — alguém mexeu no payload sem reassinar. Aí a rejeição é o sistema funcionando.

O que nunca fazer com um JWT

Se o 401 vier acompanhado de erro no console do navegador em vez da API, talvez nem seja o token — pode ser o navegador barrando a requisição antes. Isso é assunto de CORS, e o artigo de proxy reverso explica de onde os cabeçalhos vêm.

Newsletter

Receba os artigos novos por e-mail

Sem spam. Só o aviso quando sai um tutorial ou artigo novo.