Descodificar um JSON Web Token (JWT)
- Painel
- Documentação
- API
O que é um JWT (JSON Web Token)?
Um JSON Web Token, abreviado JWT (pronuncia-se "jot"), é um formato compacto definido pela RFC 7519 que permite transportar uma série de reivindicações (claims) entre duas partes. O JWT, ou jeton JWT, é hoje o formato dominante para veicular uma identidade autenticada numa API HTTP. Um JWT apresenta-se como uma cadeia ASCII composta por três segmentos separados por pontos:
header.payload.signature
Cada segmento é codificado em Base64URL, uma variante de Base64 sem padding
= e que substitui + por - e / por _
para poder circular num URL ou num cabeçalho HTTP sem escape adicional.
Importante: um JWT NÃO está cifrado. O formato JWT padrão (JWS) é simplesmente assinado: a assinatura garante a integridade do conteúdo, mas não traz qualquer confidencialidade. Qualquer pessoa pode descodificar o payload de um JWT com um simples Base64URL inverso, como faz esta ferramenta jwt decode online.
Anatomia de um JWT
Um json web token é composto por três partes bem distintas, cada uma desempenhando um papel preciso no mecanismo de autenticação:
1. Header
O header é um objeto JSON que descreve como o token é assinado. Contém no mínimo:
alg(algorithm): o algoritmo de assinatura utilizado. Valores típicos:HS256,RS256,ES256,EdDSA.typ(type): o tipo do token, quase sempre"JWT".kid(key ID): facultativo, identifica que chave deve ser utilizada para verificar a assinatura. Prático na presença de um parque de chaves em rotação (JWKS).
2. Payload
O payload contém as claims, ou seja as reivindicações que o emissor faz a respeito do utilizador ou da sessão. A RFC 7519 define sete claims padrão (registered claims):
iss(issuer): quem emitiu o token, por exemplo"https://accounts.google.com".sub(subject): a quem pertence o token, na prática o identificador do utilizador.aud(audience): a quem se destina o token. Evita que um token emitido para a API A seja aceite pela API B.exp(expiration time): timestamp Unix após o qual o token deixa de ser válido.nbf(not before): timestamp antes do qual o token ainda não está ativo.iat(issued at): timestamp de emissão do token.jti(JWT ID): identificador único do token, utilizado para a revogação e a prevenção de replay.
A estas claims padrão acrescentam-se geralmente claims custom próprias da
aplicação (roles, scope, tenant_id, email,
permissions...).
3. Signature
A assinatura é um resumo criptográfico calculado sobre
base64url(header) + "." + base64url(payload) com uma chave. É ela que prova
que ninguém modificou o header nem o payload desde a emissão. Os algoritmos mais comuns:
- HS256 / HS384 / HS512: assinatura simétrica HMAC-SHA. Uma chave secreta partilhada entre o emissor e o verificador. Simples, mas inadequada assim que há mais do que um consumidor.
- RS256 / RS384 / RS512: assinatura assimétrica RSA. O emissor assina com a sua chave privada, qualquer consumidor verifica com a chave pública correspondente. Padrão de facto para OAuth2 e OpenID Connect.
- ES256 / ES384 / ES512: assinatura assimétrica ECDSA. Mesmas propriedades que RS256 mas com chaves e assinaturas muito mais curtas.
- EdDSA (Ed25519): assinatura assimétrica moderna, rápida e compacta.
Mais uma vez: a assinatura protege a integridade, não a confidencialidade. O payload permanece legível por quem possui o token.
Porquê descodificar um JWT?
A operação jwt token decode responde a várias necessidades concretas para um programador ou um engenheiro de segurança:
- Debug de autenticação: a sua API devolve um 401 ou um 403, quer ver
o que está realmente no payload (
sub,scope,roles,exp) em vez de adivinhar. - Verificar as claims: confirmar que um token contém mesmo a reivindicação
esperada (por exemplo
tenant_idoupermissions) antes de procurar noutro lado da cadeia de autorização. - Ler a expiração: converter o timestamp
expem data humana para confirmar que um token está mesmo expirado, ou, pelo contrário, que ainda devia ser válido. - Auditoria de segurança: certificar-se de que um serviço terceiro não fuga informações sensíveis no payload (e-mails, identificadores internos, dados pessoais).
- Formação e compreensão: ver concretamente como é um jsonwebtoken que sai de um fornecedor OAuth (Google, Auth0, Keycloak, AWS Cognito) para perceber a mecânica sem mergulhar na documentação.
- Exploração de tokens públicos: inspecionar um JWT encontrado em logs, num cookie ou numa troca OAuth intercetada.
Decoder vs Verifier: a distinção crítica
As duas operações parecem próximas mas nada têm a ver em termos de garantias de segurança:
- Descodificar um JWT consiste em dividir a cadeia pelos
.e aplicar um Base64URL inverso aos dois primeiros segmentos. É uma simples leitura, ao alcance de qualquer script de três linhas. Não é feita qualquer verificação de assinatura. - Verificar um JWT consiste em recalcular a assinatura a partir do header, do payload e de uma chave, e comparar o resultado com a assinatura presente no token. É isto que garante que o token não foi falsificado.
Conclusão prática: descodificar não é confiar. Enquanto a assinatura não tiver sido verificada com a chave certa, o conteúdo do payload pode ser totalmente falso. Para a fase de confiança, utilize o nosso JWT Verifier.
Como utilizar
- Obtenha o JWT a inspecionar, por exemplo a partir de um cabeçalho
Authorization: Bearer <jwt>, de um cookie de sessão, dolocalStoragedo navegador, ou de um log aplicacional. - Cole a cadeia completa no campo de entrada. Os três segmentos devem permanecer separados por pontos.
- A ferramenta mostra imediatamente o header descodificado em JSON formatado, com o algoritmo e o tipo.
- O payload é depois descodificado e mostrado. Vê aí todas as claims padrão e custom.
- A ferramenta também indica a informação de assinatura (algoritmo declarado, comprimento), sem a verificar.
- Para confirmar que o token não foi falsificado, mude para o nosso JWT Verifier com a chave pública ou o segredo esperado.
Toda a descodificação é efetuada no seu navegador em JavaScript: o seu token nunca é enviado para os nossos servidores.
JWT e segurança: armadilhas a evitar
NUNCA armazene dados sensíveis no payload de um JWT assinado.
Palavras-passe, números de cartão bancário, dados médicos, segredos de API, identificadores internos críticos: tudo o que está no payload é legível por quem possui o token, incluindo o próprio utilizador através das ferramentas de programador do seu navegador. A assinatura não esconde nada, apenas prova que o emissor é quem afirma ser.
Algumas regras de ouro para usar bem os JWT em produção:
- Verificar sempre a assinatura no servidor antes de conceder qualquer direito. O nosso JWT Verifier ilustra exatamente esta operação.
- Preferir RS256 ou ES256 a HS256 para APIs públicas. A assinatura assimétrica evita partilhar um segredo entre o emissor e cada consumidor.
- Respeitar sempre a claim
exp. Um JWT sem expiração ou com uma expiração demasiado distante é uma bomba-relógio em caso de fuga. - Validar
isseaudno servidor, para evitar que um token legítimo emitido para outro serviço seja aceite por engano. - Recusar
alg: "none"na verificação. É uma falha clássica que permite a um atacante forjar qualquer payload. - Manter durações de vida curtas (15 minutos, por exemplo) e combinar com um refresh token mais longo mas revogável no servidor.
Exemplo de token JWT descodificado
Eis um JWT típico:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiSm9obiIsImlhdCI6MTUxNjIzOTAyMn0.jrU9j8LZcRK2_BZjqXjU7lEpJbkqmXfTQIu9vT45j-I
Uma vez descodificado, eis o seu conteúdo:
// Header
{
"alg": "HS256",
"typ": "JWT"
}
// Payload
{
"sub": "123",
"name": "John",
"iat": 1516239022
}
// Signature (binaire, encodé en Base64URL)
HMACSHA256(
base64url(header) + "." + base64url(payload),
secret
)
Onde encontrar um JWT para copiar?
Na prática, um JWT para decifrar (no sentido de descodificar) vem mais frequentemente de um destes locais:
- Cookie HTTP: abra as ferramentas de programador (F12), separador
Application ou Storage, depois Cookies. Identifique um cookie chamado
access_token,jwt,sessionou semelhante. localStorage/sessionStorage: mesmo painel, secção Local Storage. Muitas SPA armazenam aí o seu token numa chavetokenouauth.- Cabeçalho
Authorization: separador Network, selecionar um pedido de API, ler o cabeçalhoAuthorization: Bearer <jwt>. Copiar apenas a parte depois deBearer. - Logs do servidor: um JWT aparece por vezes nos logs de uma gateway ou de um reverse proxy (a evitar em produção, mas útil em debug).
Perguntas frequentes
O JWT é cifrado ou em claro?
Um JWT assinado (formato JWS) está apenas codificado em Base64URL, não cifrado. Qualquer pessoa que intercete um token pode ler o payload em segundos. Se tiver de transportar dados realmente confidenciais no token, é preciso utilizar o formato JWE (JSON Web Encryption), que adiciona uma camada de cifragem por cima da assinatura. Na prática, o JWE continua raro: prefere-se não colocar dados sensíveis num token e manter as informações críticas em base no servidor.
Como revogar um JWT antes da sua expiração?
É um dos pontos fracos do JWT: por construção, o servidor não precisa de armazenar
o estado do token, portanto também não sabe como o marcar como revogado. Existem três abordagens.
Lista de revogação: manter no servidor a lista dos
jti invalidados, e consultá-la em cada pedido. Durações de vida curtas:
emitir access tokens válidos 5 a 15 minutos, e utilizar um refresh token revogável no
servidor para gerar novos. Rotação da chave de assinatura: invalidar
toda uma geração de tokens mudando a chave. A segunda abordagem é de longe a mais
difundida.
Qual a diferença entre um JWT e uma sessão clássica?
Uma sessão clássica armazena um identificador opaco no lado do cliente (geralmente num cookie) e conserva todos os dados associados (utilizador, direitos, expiração) em memória ou em base no servidor. Um JWT, pelo contrário, transporta diretamente esses dados no token assinado. Vantagem do JWT: o servidor não precisa de armazenar sessão, o que simplifica o escalamento horizontal e a arquitetura de microsserviços. Inconvenientes: a revogação é mais complexa, o token é mais volumoso em cada pedido, e a mínima fuga expõe o payload.
Diferença entre JWT, JWS e JWE?
JWT (RFC 7519) é um formato de token genérico. Pode ser implementado de duas formas concretas: JWS (RFC 7515, JSON Web Signature) que se limita a assinar o payload, e JWE (RFC 7516, JSON Web Encryption) que o cifra. Na prática, quando se fala de "JWT" sem precisão, fala-se quase sempre de um JWS: um token assinado mas legível por todos. O JWE é utilizado em contextos onde a confidencialidade do payload é indispensável, por exemplo em alguns cenários OpenID Connect avançados.
O meu JWT não é aceite pela API, porquê?
As causas clássicas são, por ordem de frequência: token expirado (verifique
a claim exp), assinatura inválida (chave secreta ou chave pública
não corresponde à utilizada pelo emissor), mau aud
(o token foi emitido para outro serviço), mau iss
(o emissor declarado não é o esperado), algoritmo recusado (a API exige
por exemplo RS256 e recebe um HS256), relógios dessincronizados entre
o emissor e o verificador (joga com exp e nbf). Descodificar o
token com esta ferramenta permite já eliminar metade das hipóteses lendo diretamente as
claims.
Como gerar um JWT?
A maioria das linguagens dispõe de uma biblioteca dedicada: jsonwebtoken em
Node.js, PyJWT em Python, lcobucci/jwt ou
firebase/php-jwt em PHP, jjwt em Java, golang-jwt/jwt
em Go. Todas recebem na entrada um objeto payload, uma chave e um algoritmo, e devolvem a
cadeia header.payload.signature pronta a enviar. É fortemente desaconselhado
implementar a geração à mão: a criptografia comporta demasiadas armadilhas (comparações
não constantes, gestão incorreta de alg: none, etc.).
O decoder aceita um JWT expirado?
Sim. O decoder limita-se a mostrar o conteúdo do token sem fazer juízo sobre a sua
validade temporal. Não avalia nem exp, nem nbf, nem a assinatura.
É útil para perceber porquê um token foi rejeitado por uma API: pode-se
comparar o valor de exp com a hora atual para confirmar que está mesmo
expirado.
O meu JWT é válido se o decoder o mostra corretamente?
Não. A apresentação prova apenas que a cadeia está bem formada (três segmentos separados por pontos, codificação Base64URL correta, JSON válido no header e no payload). Não diz nada sobre a autenticidade do token. Um JWT totalmente falsificado pode apresentar-se sem erro num decoder, é precisamente para isso que se deve passar a um verifier.
Exemplo de pedido
curl -X POST https://cdrn.fr/api/v1/tools/jwt-decoder/execute \
-H "Content-Type: application/json" \
-d '{"token":"..."}'
Esquema de entrada
| Campo | Tipo | Obrigatório | Predefinição |
|---|---|---|---|
token |
text | ✓ | – |
Pontos de acesso
GET https://cdrn.fr/api/v1/tools- lista todas as ferramentas disponíveisGET https://cdrn.fr/api/v1/tools/jwt-decoder- obtém o esquema desta ferramentaPOST https://cdrn.fr/api/v1/tools/jwt-decoder/execute- executa esta ferramenta com um payload JSON