Como decodificar um token JWT

Para decodificar um JWT, separe o token nos dois pontos e decodifique em Base64url as duas primeiras partes: a primeira é o header (algoritmo e tipo do token) e a segunda é o payload com as claims, ambos em JSON simples. Decodificar não exige chave, porque um JWT é assinado e não criptografado; a chave só é necessária para verificar a terceira parte, a assinatura. O decodificador desta página faz as duas coisas e nunca envia o token para lugar nenhum.

6 min de leitura

Decodificando em um passo

Um JSON Web Token tem esta cara: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMifQ.assinatura, ou seja, três strings em Base64url unidas por pontos. Todo JWT começa com eyJ porque é assim que os caracteres {" ficam em Base64.

Cole o token na ferramenta abaixo. O prefixo Bearer copiado de um header Authorization é aceito. Você vê o header e o payload como JSON formatado, as claims exp, iat, nbf e auth_time como datas no seu horário local com uma indicação relativa, e uma linha de status que diz se o token expirou ou se ainda não é válido. Para conferir a assinatura, digite o segredo compartilhado ou a chave pública em Segredo ou chave pública (opcional).

Experimente aqui: Decodificador JWT

Abrir a página completa da ferramenta

As três partes de um JWT

  • Header: um pequeno objeto JSON como {"alg":"HS256","typ":"JWT"}. alg indica o algoritmo de assinatura; kid, quando existe, identifica qual chave foi usada, o que ajuda quando o emissor faz rotação de chaves.
  • Payload: as claims, isto é, afirmações sobre o usuário e o token, por exemplo o ID do usuário, o emissor, o público, os perfis de acesso e o horário de expiração. Qualquer pessoa que tenha o token consegue lê-las.
  • Assinatura: calculada sobre o header e o payload codificados com um segredo (HMAC) ou uma chave privada (RSA ou curva elíptica). Ela prova que as duas primeiras partes não foram alteradas e que foram emitidas por quem tem a chave.
  • Um token com cinco partes em vez de três é um JWE criptografado. O payload dele não pode ser lido sem a chave privada, e a ferramenta avisa quando você cola um.

Claims comuns e o que significam

O padrão JWT (RFC 7519) registra alguns nomes curtos de claims. Os horários são valores NumericDate: segundos desde 1º de janeiro de 1970 UTC, não milissegundos. Confundir os dois é um bug clássico, por exemplo comparar exp com o Date.now() do JavaScript, que devolve milissegundos.

ClaimNomeSignificado
issIssuer (emissor)Quem criou o token, muitas vezes a URL do provedor de identidade
subSubject (assunto)Sobre quem é o token, normalmente um ID de usuário
audAudience (público)Qual API ou aplicativo deve aceitá-lo
expExpiration time (expiração)Depois deste momento o token deve ser recusado
nbfNot before (não antes de)Antes deste momento o token ainda não é válido
iatIssued at (emitido em)Quando o token foi criado
jtiJWT IDID único, usado para impedir reutilização ou revogar um token
auth_timeAuthentication time (hora do login)Quando o usuário realmente fez login (OpenID Connect)

Decodificando na mão ou no código

O Base64url é diferente do Base64 padrão: usa hífen e sublinhado no lugar de + e /, e o preenchimento com = é removido. A maioria das falhas de decodificação vem de jogar uma parte do JWT direto num decodificador Base64 padrão. Troque o hífen por + e o sublinhado por /, acrescente = até o tamanho ser múltiplo de 4 e então decodifique.

Em Python, base64.urlsafe_b64decode(parte + "==") cuida do alfabeto, e o preenchimento a mais é tolerado. No console do navegador, atob funciona depois de trocar os dois caracteres, mas devolve os bytes como Latin 1, então nomes com acento no payload precisam de um TextDecoder para sair em UTF-8 correto. Bibliotecas como PyJWT, jsonwebtoken para Node.js ou System.IdentityModel.Tokens.Jwt para .NET decodificam e verificam numa única chamada; em produção use a função que verifica, não um atalho que só decodifica.

Para uma olhada rápida, uma ferramenta é mais prática e evita deixar o token no histórico do terminal.

Decodificar não é verificar

Ler o payload mostra o que o token afirma; não prova que as afirmações são verdadeiras. Qualquer um pode criar um token com "role": "admin" e codificar em Base64. Só uma assinatura válida, conferida com a chave certa, torna o conteúdo confiável. O servidor deve sempre verificar antes de usar qualquer claim.

Na ferramenta, tokens HS256, HS384 e HS512 são verificados com o segredo compartilhado. Tokens RS, PS e ES são verificados com a chave pública do emissor em formato PEM, o bloco que começa com BEGIN PUBLIC KEY. Se o seu provedor de identidade publica as chaves só como uma lista JWKS, converta antes para PEM a chave correspondente (aquela cujo kid bate com o do header). O resultado aparece como A assinatura é válida ou A assinatura não corresponde à chave. Se você colar uma chave privada, a ferramenta pede a pública no lugar dela.

Fique atento a estes sinais de alerta: alg definido como none (o token não tem assinatura nenhuma, e a ferramenta o marca como sem assinatura), um algoritmo inesperado (um servidor que espera RS256 nunca deve aceitar um token HS256, um ataque conhecido) e tokens cujo iss ou aud não batem com o seu sistema.

Resolvendo tokens expirados e inválidos

  • Token expirado: confira a data de exp na seção Datas. Tokens de acesso muitas vezes vivem só de 5 a 60 minutos de propósito; o aplicativo deve usar um refresh token para obter um novo.
  • Ainda não é válido: nbf ou iat está no futuro, o que normalmente quer dizer que o relógio do servidor e o do emissor estão diferentes. Muitas bibliotecas toleram uma pequena diferença de relógio, de alguns segundos a alguns minutos; acerte o relógio com sincronização de horário.
  • Isto não parece um JWT: o token foi cortado, ficou entre aspas ou ganhou espaços ao ser copiado. Copie de novo do header ou do cookie original.
  • Não foi possível ler o header ou o payload: falta uma parte do token. Tokens longos muitas vezes aparecem cortados nos logs.
  • A assinatura não corresponde: segredo errado, chave pública de outro ambiente (homologação em vez de produção), chave que já foi trocada ou token que foi alterado.

Lide com tokens com segurança

Um token de acesso válido funciona como uma senha até expirar. Não cole tokens ativos de produção em sites que os enviam a um servidor, e não publique tokens em chamados ou no chat. Este decodificador roda inteiro no seu navegador: o token não é enviado, registrado nem guardado.

Do lado de quem emite, mantenha o payload pequeno e sem segredos. Como qualquer um pode ler, nunca coloque senhas, chaves de API ou dados pessoais que o cliente não deve ver dentro de um JWT. Guarde o ID do usuário e os perfis e busque todo o resto no servidor.

Passo a passo

  1. Cole o tokenCole o JWT no campo de entrada. O prefixo Bearer pode ficar.
  2. Leia o header e o payloadO header e o payload aparecem como JSON formatado, com as datas do token no seu horário local.
  3. Confira o statusA linha de status mostra se o token expirou, ainda não é válido, está sem assinatura ou criptografado.
  4. Verifique a assinaturaDigite o segredo compartilhado para algoritmos HS ou a chave pública PEM para RS, PS e ES e veja se a assinatura é válida.

Perguntas frequentes

Dá para decodificar um JWT sem a chave secreta?

Sim. O header e o payload são apenas codificados em Base64url, então qualquer um consegue lê-los. O segredo ou a chave pública só são necessários para verificar a assinatura.

É seguro colar meu token neste decodificador?

Sim. A decodificação e a verificação rodam no seu navegador, e o token nunca é enviado a um servidor nem guardado. É grátis e funciona sem internet depois que a página carrega.

Como sei quando um JWT expira?

Veja a claim exp, um timestamp Unix em segundos. A ferramenta converte para a sua data e hora local e diz há quanto tempo expirou ou quanto tempo ainda falta.

Quais algoritmos de assinatura podem ser verificados?

HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384 e ES512.

Um JWT é criptografado?

Um JWT comum (JWS) é assinado, não criptografado, então o conteúdo pode ser lido. Tokens criptografados (JWE) têm cinco partes e precisam da chave privada para serem lidos.

Por que o payload decodificado mostra caracteres estranhos?

Provavelmente o payload foi decodificado como Latin 1 em vez de UTF-8, ou o token foi copiado pela metade. Esta ferramenta decodifica UTF-8 corretamente, então nomes com acento ou de outros alfabetos aparecem certos.