Os tokens JWT aparecem em quase todos os aplicativos web modernos — cabeçalhos de autenticação, fluxos de atualização, controle de acesso a APIs. Eles também são uma das normas mais mal utilizadas no mundo real. Se você estiver construindo com eles, entender o que está dentro do token, o que significa decodificar versus verificar e quais atalhos quebram silenciosamente sua segurança é indispensável.
A Anatomia de um JWT
Um JWT é três strings base64url codificadas unidas por pontos:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImVtYWlsIjoiYWxpY2VAZXhhbXBsZS5jb20iLCJpYXQiOjE3MTI3NjQ4MDAsImV4cCI6MTcxMjg1MTIwMH0.4Xr8mNkZQWpH2TvL9uY3sKdJwFqBzEcAoMnRiVePxlU
- Cabeçalho — algoritmo e tipo de token (
alg,typ) - Carga útil — as declarações (dados que seu aplicativo realmente precisa)
- Assinatura — assinatura HMAC ou RSA sobre as duas primeiras partes
Decodificado, o payload parece assim:
{
"sub": "user_123",
"email": "alice@example.com",
"iat": 1712764800,
"exp": 1712851200
}
Nada aqui está criptografado. Qualquer pessoa que tenha o token pode ler esses valores. A assinatura prova apenas que o token não foi alterado após sua emissão — ela não oculta o conteúdo.
Decodificar não é verificar
Essa distinção confunde mais desenvolvedores do que deveria.
Decodificação divide o token pelos pontos e decodifica cada seção com base64url. Não é necessário um segredo — qualquer ferramenta ou linha de comando pode fazê-lo. Se você quiser decodificar um JWT online sem instalar nada, cole o token no IO Tools Decodificador JWT e obtenha imediatamente a separação do cabeçalho, payload e expiração.
Verificação verifica se a assinatura é válida usando o segredo (ou a chave pública para algoritmos assimétricos). Também confirma que o token não expirou e que as declarações correspondem ao que seu aplicativo espera. Ignorar a verificação e confiar em um token decodificado é como ocorre a contorno de autenticação.
Aqui está um snippet em Node.js que verifica um JWT e trata os casos comuns:
import jwt from 'jsonwebtoken';
const SECRET = process.env.JWT_SECRET;
function verifyToken(token) {
try {
const payload = jwt.verify(token, SECRET, {
algorithms: ['HS256'], // whitelist — never allow 'none'
audience: 'myapp', // validate aud claim
});
// jwt.verify throws if exp is in the past, but be explicit:
if (payload.exp < Math.floor(Date.now() / 1000)) {
throw new Error('Token expired');
}
return payload;
} catch (err) {
// Never silently swallow verification failures
throw new Error(`Invalid token: ${err.message}`);
}
}
Declarações que devem ser validadas
O especificação JWT define declarações padrão que seu servidor deve verificar ativamente, e não apenas ler:
| Declaração | Significado | Validar? |
|---|---|---|
exp | Horário de expiração | Sempre — tokens obsoletos são uma superfície real de ataque |
iat | Horário de emissão | Opcional, útil para verificações de max-age |
sub | Assunto (geralmente ID do usuário) | Sim — confirme que ele corresponde ao usuário esperado |
aud | Audência intencionada | Sim — impede que tokens de um serviço A sejam usados em um serviço B |
A maioria das bibliotecas JWT valida exp automaticamente — mas apenas se você configurar. Leia as documentações da sua biblioteca. Não assuma que está ativa por padrão.
Três Erros que Queimam Desenvolvedores
1. O alg: none Ataque
A especificação JWT permite um valor de algoritmo de none, o que significa sem assinatura. Algumas bibliotecas — especialmente as antigas — aceitam isso e ignoram completamente a verificação de assinatura. Um atacante remove a assinatura, define "alg": "none" no cabeçalho e falsifica declarações arbitrárias. O servidor acredita.
Solução: liste explicitamente os algoritmos quando se verifica. Nunca aceite none. O snippet acima demonstra isso com algorithms: ['HS256'].
2. Não Validar a Expiração
Decodificar um token e confiar no payload sem verificar exp significa que um token emitido há meses ainda é aceito. Se a sessão do usuário foi revogada ou se um atacante roubou um token antigo, seu aplicativo nunca saberia.
Solução: trate a expiração como obrigatória, não opcional. Para verificar quando um token específico expira, IO Tools Verificador de Expiração JWT decodifica a exp declaração e diz exatamente quanto tempo resta — útil para depuração de fluxos de atualização sem escrever código.
3. Armazenar JWTs em localStorage
O localStorage é acessível por qualquer JavaScript na página. Uma única vulnerabilidade XSS significa que um atacante pode extrair silenciosamente o token de autenticação do usuário. Aqui está como as opções de armazenamento se compõem:
| Armazenamento | Risco XSS | Risco CSRF | Acessível por JavaScript | Notas |
|---|---|---|---|---|
| localStorage | Alto | Nenhum | Sim | Evite para tokens de autenticação |
| sessionStorage | Alto | Nenhum | Sim | Mesmas riscos que localStorage |
| Cookie httpOnly | Nenhum | Médio | Não | Melhor para autenticação; combine com SameSite + token CSRF |
| Em memória (variável JS) | Baixo | Nenhum | Sim (mesmo contexto) | Perdido ao refrescar; adequado para tokens de curta duração |
Cookies httpOnly não podem ser lidos pelo JavaScript, eliminando completamente o vetor de roubo por XSS. A desvantagem é a exposição a CSRF, que você trata com SameSite=Strict ou um token CSRF.
JWTs versus Sessões: A Verdadeira Troca
Os JWTs são sem estado — o servidor os valida sem consultar um banco de dados. Isso é útil em sistemas distribuídos onde você não quer que cada serviço acesse um armazenamento compartilhado de sessões.
Mas o sem estado tem um custo real: você não pode revogar um JWT antes de expirar. Se um usuário sair ou for comprometido, o token permanece válido até exp. Soluções (listas de bloqueio de tokens, expiração curta + tokens de atualização) existem, mas adicionam complexidade e muitas vezes recriam o que um armazenamento de sessão já faz.
Use JWTs quando: você tem múltiplos serviços autenticando solicitações independentemente, deseja incluir papéis e permissões diretamente no token, ou seus tokens são de curta duração e a latência de revogação é aceitável.
Use sessões quando: você precisa de revogação imediata (o logout deve realmente funcionar), você está construindo um aplicativo renderizado no servidor, ou a simplicidade supera a escalabilidade sem estado.
Inspeção de um Token em Segundos
Precisa ver o que está dentro de um JWT agora? Terminal:
echo "YOUR.JWT.HERE" | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool
Ou pule o terminal — cole o token no IO Tools Decodificador JWT para obter uma separação formatada do cabeçalho e do payload. Nenhum desses métodos verifica a assinatura; eles apenas decodificam. Para uma rápida leitura de expiração sem escrever código, o Verificador de Expiração JWT fornece exatamente a marcação de tempo e o tempo restante.
Você também pode gostar
Instale nossas extensões
Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida
恵 O placar chegou!
Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!
Ferramentas essenciais
Ver tudo Novas chegadas
Ver tudoAtualizar: Nosso ferramenta mais recente foi adicionado em 5 de maio de 2026
