Estrutura de um JWT
Um JSON Web Token são três segmentos Base64url unidos por pontos: um header que nomeia o algoritmo de assinatura, um payload que carrega claims sobre quem você é e até quando, e uma assinatura criptográfica sobre os dois primeiros. A estrutura, definida no RFC 7519, pode ser inspecionada por qualquer um — a assinatura protege a integridade, não o sigilo.
Estrutura de um JWT: explicação
Quando um serviço quer entregar a você uma prova de login que qualquer um dos servidores dele consegue verificar sem um armazenamento de sessão compartilhado, ele entrega um JWT. O token é uma string compacta e segura para URLs — você já viu: três pedaços de texto aparentemente sem nexo, separados por dois pontinhos, viajando em um header Authorization ou em um cookie. O texto sem nexo não é criptografia; é Base64url, e decodifica em uma linha de código.
O formato descende de uma família de especificações: o RFC 7519 define o token em si, o RFC 7515 (JWS) define como a assinatura o envolve, e o grupo de trabalho JOSE forneceu os nomes de claims registrados e os identificadores de algoritmos. Essa linhagem explica a propriedade mais mal compreendida do formato, tratada sem rodeios abaixo — assinado significa à prova de adulteração, não secreto.
Este guia decodifica um token real segmento por segmento, lista as claims registradas com a semântica exata de cada uma, compara as duas famílias de assinatura que você vai encontrar — HS256 e RS256 — e enuncia as regras que mantêm os tokens seguros, incluindo por que a verificação pertence ao servidor, com a chave do emissor, a cada requisição.
Tudo o que está abaixo você faz com um token real em segundos — o Decodificador de JWT divide e decodifica os três segmentos localmente, sinalizando as marcações de tempo conforme avança.
Como cada segmento é Base64url, o guia de Base64 é a leitura complementar: ele explica o alfabeto, o padding descartado e por que os tokens são seguros para URLs.
Três segmentos, dois pontos de separação
A serialização compacta é header.payload.signature — cada segmento codificado em Base64url de forma independente, com os pontos como separadores literais. A codificação é deliberadamente sem padding, então um token contém apenas letras, dígitos, hífens e underscores: seguro em URLs, headers e cookies sem precisar de escape. Decodificar os dois primeiros segmentos não é um hack — é o modo pretendido de inspecionar um token; o terceiro segmento é onde a verificação acontece.
Um token real, com uma assinatura calculada sobre ele, decodifica exatamente assim:
Um token com uma assinatura HS256 válida
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJzdWIiOiJ1c2VyXzg0OTIiLCJhdWQiOiJhcGkuZXhhbXBsZS5jb20iLCJpYXQiOjE3NjcyMjU2MDAsImV4cCI6MTc2NzMxMjAwMCwianRpIjoiYjBmNmMyZDQtNGU3YS00YzFmLTlhMmItM2Q1ZTdmOWExYzNlIn0.iDPqw4BRxZtM064Y3EH83XLB0cgEjbj5snSXeM846VY
Os dois primeiros segmentos, decodificados
{"alg":"HS256","typ":"JWT"}
{"iss":"https://auth.example.com","sub":"user_8492",
"aud":"api.example.com","iat":1767225600,
"exp":1767312000,
"jti":"b0f6c2d4-4e7a-4c1f-9a2b-3d5e7f9a1c3e"}O header: o sumário do token
O header é um pequeno objeto JSON — formalmente, o JWS Protected Header. Dois campos fazem quase todo o trabalho: alg nomeia o algoritmo de assinatura, e typ registra o media type, convencionalmente JWT. Um terceiro, kid (key ID), aponta o verificador para a chave certa quando um emissor publica várias. O header é assinado, mas nunca criptografado, e só é confiável depois que a assinatura é verificada — até lá, alg é uma claim, não um fato.
| Campo | Significado | Exemplo |
|---|---|---|
| alg | Algoritmo de assinatura — a primeira decisão de roteamento do verificador | HS256, RS256, ES256 |
| typ | Media type; JWT por convenção, ignorado pela maioria das bibliotecas | JWT |
| kid | Qual chave usar para verificar, quando várias são publicadas | 2026-01-signing |
| none | O pseudoalgoritmo que significa 'sem assinatura' — rejeite, a menos que tenha sido realmente solicitado | (um alvo de ataque conhecido) |
O payload: as claims registradas e o que cada uma promete
O payload é um objeto JSON de claims. Sete são registradas pelo RFC 7519 com significados precisos e interoperáveis; todo o resto é privado ao emissor e à audiência. Os tempos são valores NumericDate — segundos desde a época Unix, não milissegundos —, e as claims de tempo são apenas informativas para o verificador: checá-las é trabalho do verificador, não algo que o formato imponha.
| Claim | Nome completo | O que afirma |
|---|---|---|
| iss | Issuer | Quem criou e assinou o token — uma URL ou um nome |
| sub | Subject | Sobre quem é o token — um identificador de usuário ou cliente |
| aud | Audience | Para quais destinatários o token é; os verificadores o rejeitam se não estiverem na lista |
| exp | Expiration | Prazo em segundos desde a época; inválido depois de passado |
| nbf | Não antes de | Momento mais cedo em que o token pode ser aceito |
| iat | Emitido em | Quando o token foi criado — evidência de idade, não uma expiração |
| jti | JWT ID | Um identificador único para este token — o gancho para listas de revogação |
A assinatura: HS256, RS256 e como a verificação funciona
A assinatura é calculada sobre a entrada de assinatura — o header codificado, um ponto, o payload codificado — usando o algoritmo que o header nomeia. HS256 é HMAC-SHA256 com um segredo compartilhado: rápido e simétrico, apropriado apenas quando quem assina e todo verificador formam um único domínio de confiança, porque qualquer um que tenha o segredo pode cunhar tokens. RS256 é RSA: o emissor assina com uma chave privada e qualquer um — incluindo um navegador — pode verificar com a chave pública publicada, e é isso que faz dele o padrão para protocolos federados como OAuth 2.0 e OpenID Connect.
A verificação recalcula a assinatura e compara. Esse é todo o mecanismo — e é por isso que o header alg sozinho decide como a checagem roda. As bibliotecas se endureceram depois dos ataques de confusão de algoritmo do começo dos anos 2010: um token que alega alg none, ou um token RS256 reprocessado como HS256 usando a chave pública como segredo do HMAC, só verifica contra verificadores que não fixam o algoritmo esperado.
As duas famílias num relance
HS256: HMAC-SHA256(secret, header + '.' + payload)
quem assina e quem verifica compartilham o segredo
RS256: RSA-SHA256(private key, header + '.' + payload)
o emissor assina; qualquer um verifica com a chave públicaA regra que decorre daí
Fixe o algoritmo esperado para cada emissor. Nunca o deduza apenas do cabeçalho do próprio token. Nunca aceite alg: none.
Assinado, não lacrado: o que a assinatura não faz
A assinatura prova que o token foi emitido por quem detém a chave e que não foi alterado desde então — integridade e autenticidade. Ela não fornece confidencialidade nenhuma: Base64url é uma codificação, e o payload pode ser lido por qualquer um que veja o token, incluindo extensões de navegador, proxies quando os tokens viajam em URLs e coletores de log. Daí as regras permanentes: nunca coloque segredos em um payload de JWT, nunca envie tokens em URLs e trate cada claim decodificada como dado, não como decisão.
Esse último ponto é a armadilha do lado do cliente. Um navegador pode decodificar um token e ler exp ou sub — mas não consegue verificar o token de forma significativa, porque não detém a chave do emissor: com HS256, o segredo nunca deve chegar ao navegador; com RS256, uma checagem no cliente não prova nada sobre o que o portador pode acessar. Clientes podem inspecionar tokens para apresentação — mostrar um nome, avisar sobre expiração —, mas o servidor deve verificar a assinatura e cada claim a cada requisição. Inspecionar não é verificar, e legível não é autorizado.
Inspecionar tokens com segurança — o ciclo prático
Um ciclo disciplinado de inspeção leva segundos: decodifique o header e o payload, cheque exp e nbf contra o relógio, confirme que iss e aud são o que você espera e só então — no servidor — verifique a assinatura com um algoritmo fixado e a chave certa. Tudo, exceto a verificação final, é processamento de texto puro, e é por isso que um decodificador que roda inteiramente no seu navegador é a ferramenta certa: tokens reais são credenciais bearer, e credenciais devem ficar em abas que você controla, não a sites que podem encaminhá-las.
Lembre do que a estrutura não pode dar a você: revogação — listas de bloqueio baseadas em jti precisam ser construídas e checadas no servidor; confidencialidade — use JWE se você precisa de tokens criptografados; e confiança — um token estruturalmente perfeito de um emissor que você nunca configurou não vale nada. A estrutura diz o que foi prometido; só a verificação diz que a promessa segue intacta.
Perguntas frequentes
É seguro colar meu token real em um decodificador de JWT?
Neste site, é, porque o decodificador roda inteiramente no seu navegador: o token nunca é enviado, nenhum servidor poderia registrá-lo em log, e a Content-Security-Policy do site bloqueia requisições de saída, então a página não consegue transmitir nem por acidente. Tenha muito mais cuidado com qualquer decodificador online — um JWT é uma credencial bearer, e qualquer um que o ler pode usá-lo até expirar.
A assinatura criptografa o conteúdo do token?
Não — a assinatura só detecta adulteração. Base64url é uma codificação reversível, não criptografia: qualquer um com o token pode ler cada claim, e é por isso que senhas e segredos nunca devem ir para o payload. Variantes confidenciais existem como JWEs — JSON Web Tokens criptografados —, mas os tokens em headers Authorization comuns são JWSs: assinados, legíveis, à prova de adulteração.
Qual é a diferença entre HS256 e RS256?
O modelo de chaves. HS256 é HMAC-SHA256 com um único segredo compartilhado: toda parte que consegue verificar tokens também pode cunhá-los, então serve a um único serviço que controlam as duas pontas. RS256 é RSA: o emissor assina com uma chave privada e os verificadores checam com uma chave pública — verificar nunca concede o poder de falsificar. Os padrões de identidade federada se apoiam no RS256 exatamente por esse motivo.
Por que os JWTs precisam ser verificados no servidor?
Porque a verificação precisa da chave do emissor e de uma decisão de autorização, e só o servidor tem os dois. Com HS256, o segredo compartilhado nunca deve chegar a um navegador; com RS256, um navegador poderia checar uma assinatura criptograficamente, mas a conclusão dele não prova nada sobre acesso — clientes podem ser modificados. O servidor reverifica a assinatura e checa iss, aud e exp a cada requisição.
O que acontece quando um JWT expira?
Nada automático — exp é uma claim que um verificador precisa checar. Um servidor em conformidade compara com a hora atual e rejeita o token assim que o prazo passa; um desleixado continua aceitando para sempre. Fluxos de refresh existem por esse motivo: access tokens de vida curta, checados a cada requisição, mais um refresh token de vida mais longa que o servidor pode revogar quando precisar.
Posso confiar em um token cuja assinatura eu não verifiquei?
Só como uma dica não autenticada. Um token não verificado pode ter sido escrito por qualquer um — o iss, o sub e até o exp dele são só texto até a checagem da assinatura passar. O modelo mental seguro: decodificar diz o que o token alega; verificar diz quem assinou essas claims e que elas seguem inalteradas. Nunca libere acesso com base na primeira.
Onde posso ler os padrões citados aqui?
Quais ferramentas relacionadas devo usar a seguir?
- Decodificar JWTDecifra o token e explica o que cada claim significaAbrir
- Como funciona o Base64Guia em linguagem simplesAbrir
- Versões de UUIDGuia em linguagem simplesAbrir
- O que é JSONGuia em linguagem simplesAbrir
- Formatar JSONIndenta, ordena chaves e remove comentáriosAbrir
- Validar JSONAponta o erro com linha e coluna e corrige num cliqueAbrir