JWT Tokens Explicados: Estrutura, Segurança e Erros Comuns
Entenda como os JSON Web Tokens funcionam, o que contém neles e as armadilhas de segurança que pegam desenvolvedores desprevenidos em produção.
JSON Web Tokens (JWTs) estão em todo lugar — eles alimentam a autenticação em SPAs, aplicativos móveis e arquiteturas de microsserviços no mundo inteiro. Mesmo assim, são um dos conceitos de segurança mais mal compreendidos no desenvolvimento web. Implementá-los de forma errada pode resultar em bypass de autenticação, escalonamento de privilégios ou comprometimento total de contas.
O que é um JWT?
Um JWT é uma string compacta e segura para URLs que codifica um conjunto de claims — afirmações sobre um usuário ou sessão. Ele tem esta aparência:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
São três segmentos codificados em Base64URL separados por pontos:
- Header — algoritmo e tipo do token
- Payload — os claims (dados do usuário)
- Signature — prova criptográfica de integridade
Cole qualquer JWT no nosso JWT Decoder para inspecionar as três partes instantaneamente, sem precisar de nenhum servidor externo.
Anatomia de um JWT
Header
{
"alg": "HS256",
"typ": "JWT"
}
alg especifica o algoritmo de assinatura. Valores comuns:
HS256— HMAC com SHA-256 (simétrico, segredo único)RS256— RSA com SHA-256 (assimétrico, chave pública/privada)ES256— ECDSA com SHA-256 (assimétrico, chaves menores)
Payload
{
"sub": "user_abc123",
"email": "alice@example.com",
"role": "admin",
"iat": 1711670400,
"exp": 1711756800
}
Claims registrados padrão:
| Claim | Significado |
|---|---|
sub |
Subject (sobre quem é o token) |
iss |
Issuer (quem criou o token) |
aud |
Audience (quem deve aceitá-lo) |
exp |
Tempo de expiração (timestamp Unix) |
iat |
Emitido em (timestamp Unix) |
nbf |
Not before (não aceitar antes deste momento) |
Signature
Para HS256:
HMAC-SHA256(base64url(header) + "." + base64url(payload), secret)
A assinatura prova que o token não foi adulterado. O payload NÃO é criptografado — ele apenas é codificado. Qualquer pessoa pode lê-lo.
Nunca armazene dados sensíveis como senhas ou números de cartão de crédito no payload de um JWT.
HS256 vs. RS256: qual escolher?
HS256 usa um único segredo compartilhado. Todo serviço que precisa verificar tokens deve ter o mesmo segredo. Simples para aplicações monolíticas, mas perigoso em arquiteturas com múltiplos serviços — se qualquer serviço for comprometido, um invasor pode forjar tokens.
RS256 usa chaves assimétricas. O servidor de autenticação assina com uma chave privada; todos os outros serviços verificam com a chave pública. Comprometer um serviço consumidor não dá ao invasor a capacidade de forjar tokens. Prefira RS256 para qualquer sistema com múltiplos serviços.
A vulnerabilidade alg: none
Um dos ataques JWT mais famosos. Algumas bibliotecas mais antigas aceitavam um token com "alg": "none" e sem assinatura — tratando-o como válido. Um invasor poderia criar:
{ "alg": "none" }
com qualquer payload e bypassar a autenticação completamente.
Correção: Sempre especifique explicitamente os algoritmos permitidos na sua biblioteca JWT. Nunca aceite none.
// ❌ Perigoso
jwt.verify(token, secret);
// ✅ Seguro — aceita apenas HS256
jwt.verify(token, secret, { algorithms: ["HS256"] });
Ataque de confusão de algoritmo
Outra vulnerabilidade crítica: se sua biblioteca detecta automaticamente o algoritmo a partir do header, um invasor pode alterar RS256 para HS256 e assinar o token usando a chave pública como segredo HMAC (que, por definição, é pública).
Correção: Sempre defina o algoritmo esperado no código. Nunca confie no header alg.
Armazenamento de tokens: onde guardar JWTs
| Armazenamento | Risco de XSS | Risco de CSRF | Observações |
|---|---|---|---|
localStorage |
Alto | Nenhum | Acessível a qualquer JS na página |
sessionStorage |
Alto | Nenhum | Limpo ao fechar a aba |
| Cookie HTTP-only | Nenhum | Médio | Melhor para apps web; use SameSite=Strict |
| Memória (variável) | Baixo | Nenhum | Perdido ao atualizar; para SPAs |
Para aplicações web, cookies HTTP-only com SameSite=Strict é a opção mais segura. Para aplicativos nativos, APIs de armazenamento seguro (Keychain, Keystore) são as mais indicadas.
Expiração e refresh tokens
Tokens de acesso de curta duração (5–15 minutos) combinados com refresh tokens de longa duração é o padrão mais adotado:
- Usuário faz login → servidor emite access token (15 min) + refresh token (7 dias, armazenado no BD)
- O cliente usa o access token para chamadas de API
- Quando o access token expira, o cliente envia o refresh token → recebe um novo access token
- No logout, invalide o refresh token no banco de dados
Isso limita o período de exposição caso um access token seja roubado.
Revogando JWTs
JWTs são stateless — uma vez emitidos, são válidos até a expiração. Isso é uma troca. Opções para revogar antes do prazo:
- Blocklist — armazene valores JTI (JWT ID) invalidados no Redis. Verifique a cada requisição.
- Expiração curta — tokens de 5 minutos limitam o raio de impacto.
- Rotação de refresh token — detecte reutilização de um token rotacionado como sinal de roubo.
Depurando com o JWT Decoder
Ao depurar problemas de autenticação, use nosso JWT Decoder para:
- Inspecionar o payload completo sem escrever código
- Verificar timestamps de expiração em formato legível
- Confirmar o algoritmo sendo utilizado
- Identificar claims inesperados ou ausentes
Toda a decodificação acontece localmente no seu navegador — os tokens nunca saem da sua máquina.
Checklist de segurança para JWT
- Use RS256 ou ES256 para arquiteturas com múltiplos serviços
- Especifique explicitamente os algoritmos permitidos na sua biblioteca
- Valide os claims
exp,isseaudem cada requisição - Armazene tokens em cookies HTTP-only para apps web
- Use tempos de vida curtos para access tokens (15 min ou menos)
- Implemente rotação de refresh token com detecção de reutilização
- Nunca coloque dados sensíveis no payload
- Use HTTPS em todo lugar — um token em texto plano equivale a não ter autenticação
JWTs são poderosos e convenientes, mas são tão seguros quanto sua implementação. Entenda a estrutura, conheça os ataques e sua camada de autenticação será sólida.