1001Ferramentas
🪙 Dev

JWT por dentro: a anatomia de um token

As três partes de um JWT, o que vai (e o que nunca deve ir) no payload, como a assinatura protege o token e por que decodificar não é confiar.

Atualizado em 30 de junho de 2026 · 7 min de leitura

As três partes de um JWT (header.payload.signature)

Um JWT — JSON Web Token, definido na RFC 7519 — é uma daquelas strings longas e embaralhadas que aparecem no cabeçalho Authorization: Bearer ... de praticamente toda API moderna. Apesar do visual intimidador, a estrutura é simples: são três blocos separados por pontos. Olhe com atenção e você acha os dois pontos:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Cada parte é um pedaço de JSON codificado em Base64URL (a variante do Base64 que troca + e / por - e _ e descarta o padding, para sobreviver dentro de uma URL). As três partes são:

ParteConteúdoPara que serve
Header{"alg":"HS256","typ":"JWT"}Diz o algoritmo da assinatura e o tipo
Payload{"sub":"1234567890","name":"John Doe","iat":1516239022}Os dados (claims) que o token carrega
SignatureSflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cA prova criptográfica de que o token é autêntico

Aquele primeiro bloco, eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9, é só o Base64URL de {"alg":"HS256","typ":"JWT"} — todo JWT HS256 começa com exatamente esses caracteres, porque o header é sempre o mesmo. Cole o token inteiro no Decodificador JWT e ele separa e decodifica as três partes na hora, mostrando o JSON legível de cada uma.

O que vai e o que NUNCA deve ir no payload

Aqui está o mal-entendido que mais causa vazamento de dados: o payload não é criptografado, apenas codificado. Base64URL é reversível por qualquer pessoa, sem chave nenhuma. Quem interceptar o token lê o conteúdo em segundos. Por isso a regra de ouro:

Nunca coloque no payload de um JWT: senha, número de cartão, CPF, token de outro sistema, chave de API ou qualquer dado que você não imprimiria num outdoor. O payload é público para quem tem o token.

O que deve ir são as chamadas claims — afirmações sobre o usuário e o próprio token. A RFC 7519 reserva sete nomes curtos e padronizados (registered claims):

ClaimSignificado
issIssuer — quem emitiu o token
subSubject — o sujeito, normalmente o ID do usuário
audAudience — para qual serviço o token vale
expExpiration — quando deixa de valer
nbfNot before — antes deste instante, é inválido
iatIssued at — quando foi emitido
jtiJWT ID — identificador único, útil para revogação

Além dessas, você pode adicionar claims próprias (role, plan, email) — apenas lembre que tudo fica visível. Quer ver os campos de um token real seu? O Decodificador JWT lista cada claim com seu valor, e converte automaticamente o exp e o iat (que são timestamps Unix) em datas legíveis.

Como a assinatura protege o token

Se qualquer um pode ler o payload, o que impede um usuário de trocar "role":"user" por "role":"admin" e ganhar superpoderes? A resposta é a terceira parte: a assinatura.

No HS256, a assinatura é calculada assim:

HMAC-SHA256( base64url(header) + "." + base64url(payload), segredo )

Ou seja, o servidor pega as duas primeiras partes já codificadas, junta com um ponto, e gera um HMAC-SHA256 usando uma chave secreta que só ele conhece. O resultado é a terceira parte. Quando o token volta numa requisição, o servidor refaz exatamente essa conta e compara: se o cliente tiver mexido em um único caractere do header ou do payload, o HMAC recalculado não bate com a assinatura enviada, e o token é rejeitado.

A segurança toda repousa no segredo. Como o atacante não o conhece, ele consegue alterar o payload, mas não consegue forjar a assinatura correspondente. É por isso que a integridade do token não depende de esconder os dados — depende de não conseguir falsificar a prova. Você pode montar um token do zero, escolher as claims e ver a assinatura sendo gerada passo a passo no Construtor de JWT (HS256); troque um caractere do segredo e observe a assinatura mudar por completo.

HS256 vs RS256

O campo alg do header decide como a assinatura é feita. Os dois algoritmos mais comuns resolvem o mesmo problema de formas opostas:

HS256 (simétrico)RS256 (assimétrico)
MecanismoHMAC com SHA-256Assinatura RSA com SHA-256
ChavesUm único segredo compartilhadoPar: chave privada + pública
Quem assinaQuem tem o segredoSó quem tem a chave privada
Quem verificaQuem tem o mesmo segredoQualquer um com a chave pública

Com HS256, quem verifica também consegue forjar, porque assinar e verificar usam a mesma chave. É perfeito quando o mesmo serviço emite e valida os tokens — um monólito, por exemplo. Já o RS256 separa os papéis: o servidor de autenticação guarda a chave privada e assina; qualquer microsserviço pode validar usando só a chave pública (em geral publicada num endpoint JWKS), sem nunca poder emitir um token falso. Por isso RS256 domina em arquiteturas distribuídas, OAuth e OpenID Connect.

Um cuidado clássico de segurança: o servidor deve fixar o algoritmo esperado. Bibliotecas antigas aceitavam "alg":"none" (token sem assinatura) ou eram enganadas por um ataque de confusão de algoritmo, em que o invasor entrega a chave pública RS256 fazendo-a passar por segredo HS256. Nunca confie cegamente no alg que vem dentro do próprio token.

Expiração, claims e validação

A claim exp é um timestamp Unix — o número de segundos desde 1º de janeiro de 1970 em UTC, não milissegundos. No nosso exemplo, iat vale 1516239022, que corresponde a 18 de janeiro de 2018. Se o token tivesse validade de 15 minutos, o exp seria 1516239022 + 900 = 1516239922. O servidor compara esse valor com o relógio atual e rejeita o token quando o tempo presente já passou do exp (em geral com uma pequena tolerância de poucos segundos para diferenças de relógio).

Validar um JWT de verdade é uma sequência, não um único passo:

  1. Conferir a estrutura: três partes separadas por ponto, cada uma Base64URL válido.
  2. Ler o header e confirmar que o alg é o que você espera (e não none).
  3. Recalcular a assinatura com o segredo/chave e comparar com a recebida.
  4. Checar exp e nbf contra o horário atual.
  5. Conferir iss e aud — o token foi emitido por quem você confia e destinado a este serviço?

O primeiro passo, o da forma, você pode inspecionar à parte com o Validador de JWT, que checa se as três partes existem e se cada uma decodifica para um JSON bem formado — útil para descobrir rapidamente se um token chegou truncado ou corrompido. Como os JWTs são, por padrão, stateless (o servidor não guarda nada), a forma normal de "revogar" um token é dar a ele uma vida curta — minutos — e renová-lo com um refresh token.

Decodificar não é o mesmo que confiar

Esta é a lição mais importante e a mais ignorada. Decodificar um JWT é trivial; confiar nele exige verificar a assinatura. Abrir o payload com Base64 e ler "role":"admin" não prova absolutamente nada — qualquer pessoa pode gerar uma string com esse conteúdo. O que estabelece confiança é o passo da assinatura, e só quem tem o segredo (HS256) ou a chave pública (RS256) consegue executá-lo.

A consequência prática vale tanto para o backend quanto para o frontend:

  • O servidor deve verificar a assinatura em toda requisição protegida antes de usar qualquer claim. Decodificar e usar sem verificar é uma falha de segurança grave.
  • O cliente (app, SPA) pode decodificar o payload para, digamos, mostrar o nome do usuário — mas jamais deve tomar decisões de segurança com base nele, porque o navegador não tem como verificar a assinatura com segurança.

Ferramentas que "abrem" um JWT — incluindo as deste site — fazem apenas a decodificação Base64. Elas mostram o conteúdo; não atestam que ele é legítimo. Use-as para depurar, entender e inspecionar tokens, e deixe a verificação criptográfica acontecer no servidor, onde o segredo vive.

Perguntas frequentes

JWT é criptografado?

Não, por padrão não. Um JWT assinado (JWS) é apenas codificado em Base64URL — qualquer um lê o payload. Existe um formato separado, o JWE (JSON Web Encryption), que de fato criptografa o conteúdo, mas é bem menos comum. Na dúvida, trate o payload de um JWT comum como público.

Posso confiar nos dados que leio ao decodificar um token?

Só depois de verificar a assinatura. A decodificação mostra o conteúdo, mas não prova que o token é autêntico nem que não foi alterado. Sem checar a assinatura com o segredo ou a chave pública, qualquer claim pode ter sido forjada.

Qual a diferença entre HS256 e RS256?

HS256 usa um único segredo compartilhado para assinar e verificar — simples, ideal quando o mesmo serviço faz as duas coisas. RS256 usa um par de chaves: a privada assina e a pública verifica, permitindo que terceiros validem o token sem poder emiti-lo. RS256 é o padrão em sistemas distribuídos e OpenID Connect.

Como invalido um JWT antes de ele expirar?

Como o token é stateless, você não o "apaga" de fato. As abordagens usuais são: manter uma lista de revogação (denylist) pelo jti, usar tokens de acesso de vida curta com refresh tokens, ou trocar o segredo de assinatura (o que invalida todos os tokens de uma vez). Vida curta + refresh é a estratégia mais comum.

Por que meu token tem só duas partes em vez de três?

Provavelmente foi truncado em algum lugar (um cabeçalho HTTP cortado, uma cópia incompleta) ou é um JWT "unsecured" com alg:none e assinatura vazia. Passe o token pelo Validador de JWT para confirmar se as três partes estão presentes e bem formadas.

Ferramentas citadas neste guia

Continue lendo