Decodificar um JWT não é verificá-lo
Um JSON Web Token, ou JWT, costuma ser apresentado como três textos separados por pontos. É fácil concluir, de forma perigosa, que aquilo que um navegador consegue decodificar é confiável. Não é. Decodificar mostra a estrutura declarada do token; verificar é uma decisão de segurança tomada por um sistema que conhece o emissor, a audiência, a política de tempo, o algoritmo e a chave esperados. Esta explicação usa uma amostra deliberadamente forjada e sem produção. Não contém utilizador real, segredo, chave privada ou credencial utilizável.
O problema
A RFC 7519 define a forma compacta do JWT com três segmentos base64url: cabeçalho, payload e assinatura. Base64url é codificação, não cifragem. Quem possui o token consegue ler os dois primeiros segmentos e um atacante também consegue escrever outros. O payload pode dizer que alguém é administrador, que expira no próximo ano ou que pertence a um emissor familiar. Até a verificação terminar, essas são apenas afirmações vindas de uma entrada não confiável.
Isso importa sempre que um token altera uma autorização. Um painel de diagnóstico pode decodificá-lo localmente para mostrar uma data ou uma claim mal formada. Esse painel não pode usar role, sub ou scope para decidir o que alguém pode fazer. Uma interface pode mostrar uma indicação de expiração, mas uma API precisa decidir por si mesma e não aceitar a interpretação do navegador. Um token pode ser correto para uma aplicação e inaceitável para outra porque a audiência pretendida é diferente.
Verificar não é confirmar apenas que existem três partes. O verificador parte de uma relação de confiança configurada: aceita poucos algoritmos, obtém uma chave por um mecanismo controlado, verifica a assinatura sobre os dados protegidos originais e avalia claims segundo política local. A RFC 8725 alerta que conteúdo controlado pelo atacante não deve escolher comportamentos críticos de validação. Um decodificador não possui esse contexto.
Exemplo prático
Este é um token de demonstração sintaticamente válido. O cabeçalho decodifica para {"alg":"HS256","typ":"JWT"}. O payload decodifica para {"sub":"demo-user","role":"admin","exp":1893456000,"iss":"https://issuer.example.invalid","aud":"demo-api"}. O terceiro segmento é apenas o texto base64url da palavra “signature”; não foi calculado com segredo e não prova nada. É uma falsificação intencional.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkZW1vLXVzZXIiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE4OTM0NTYwMDAsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuaW52YWxpZCIsImF1ZCI6ImRlbW8tYXBpIn0.c2lnbmF0dXJl
Um decodificador separa o texto nos pontos, aplica base64url aos dois primeiros segmentos e mostra campos. exp é uma NumericDate, em segundos desde a época Unix, portanto pode virar uma data para inspeção. iss é o identificador que o token declara como emissor. aud nomeia o destinatário pretendido. Valores plausíveis não demonstram que o emissor os criou, que a API atual é destinatária nem que o token pode ser aceito agora.
Se demo-user for alterado para outro sujeito, ou role de viewer para admin, e o payload for novamente codificado, o resultado continua com três segmentos bem formados. Também decodifica sem erro. Um verificador correto o rejeita porque a assinatura deixa de corresponder ao cabeçalho e payload sob a chave esperada. A amostra mostra exatamente a diferença: a análise de formato funciona antes da confiança existir.
Procedimento
Trate um token como dado operacional sensível, mesmo não sendo uma senha. Não cole um bearer token de produção num site não aprovado, ticket, chat ou captura. Para diagnóstico local, use token de desenvolvimento controlado, oculte identificadores ou inspecione no ambiente que o emitiu. Guarde apenas o mínimo para reproduzir a falha, como nomes e tipos das claims e uma conversão de expiração.
Na inspeção, confirme primeiro que a forma compacta tem exatamente três segmentos não vazios. Decodifique cabeçalho e payload como JSON UTF-8 sem lhes dar autoridade. Observe alg, mas não deixe que ele escolha a política do servidor. Confira a forma numérica de exp, nbf e iat; compare iss com o emissor esperado; e compare aud com o identificador do recurso receptor. Essas são observações de diagnóstico, não aprovação.
Para autenticação ou autorização, entregue o token compacto original a um verificador confiável. Ele deve ter lista explícita de algoritmos e tipos de chave aceitos, emissor configurado e audiência configurada. Deve verificar a assinatura antes de confiar no payload, rejeitar tokens vencidos pela sua política de relógio e aplicar controles de nbf, tipo, sujeito e autorização específica. A descoberta de chaves também precisa ser autenticada e limitada ao emissor conhecido; um cabeçalho não confiável não pode indicar uma localização arbitrária.
Depois, separe validação de identidade de autorização da aplicação. Um token verificado pode estabelecer quem emitiu uma afirmação, mas a aplicação ainda decide se esse sujeito pode executar a ação. Aplique menor privilégio, regras no servidor e controles do recurso após verificar. Registre resultados sem guardar bearer tokens inteiros. Em falhas, devolva resposta genérica e mantenha diagnósticos detalhados somente em logs operacionais protegidos.
Explicação técnica
A assinatura é calculada sobre cabeçalho e payload codificados, não sobre o objeto JSON depois que um decodificador o reformata. Isso impede aceitação silenciosa de espaços, campos reordenados ou segmentos substituídos. Em algoritmos simétricos, emissor e verificador partilham um segredo; em assimétricos, o emissor assina com chave privada e o verificador usa chave pública autenticada. Ler o payload não dá autoridade para assiná-lo.
Claims são contextuais. A RFC 7519 define nomes registados, mas deixa a política ao destinatário. exp marca quando o token não deve ser aceito, mas o sistema decide a tolerância de relógio. nbf marca início de validade. iss exige comparação exata com identificador configurado, não semelhança visual. aud pode ser texto ou lista, e uma API precisa exigir que seja destinatária. Uma claim pode estar sintaticamente correta e ser errada para o pedido atual.
A confusão de algoritmos é razão para configurar em vez de inferir. Um serviço que aceita qualquer alg anunciado pode usar um caminho inadequado. Se mistura emissores sem ligar chaves, audiências e algoritmos, pode aceitar token de outro domínio. A RFC 8725 recomenda regras mutuamente exclusivas para tipos diferentes e verificação estrita do algoritmo. São responsabilidades do servidor, não de um decodificador genérico.
Erros frequentes
Um erro comum é usar o payload decodificado como sessão. Um cliente lê role: admin e mostra rota privilegiada antes da verificação pelo backend. Ocultar botão não autoriza, mas pode confundir e revelar comportamento. Toda operação protegida precisa exigir autorização no lado confiável. Outro erro é aceitar exp apenas porque está no futuro: uma data futura não corrige assinatura, emissor, audiência ou tipo inválidos.
Também é errado registrar tokens completos ao diagnosticar decodificação. Bearer tokens podem dar acesso até expirar; logs, análise, relatórios de erro e extensões tornam-se exposição desnecessária. Redija-os e não os copie em exemplos. Um decodificador público ajuda a olhar formato, porém não conhece chaves privadas, emissores aprovados, revogação ou a API exata receptora.
Não desative verificação de assinatura para fazer teste passar. Crie emissor e chaves de teste separados, curtos e com permissões limitadas. Rejeite tokens sem assinatura salvo um formato não autenticador cuidadosamente desenhado exigir isso. Uma biblioteca não deve aceitar downgrade porque o cabeçalho pediu. Teste assinaturas alteradas, audiências inesperadas, tempos antigos e emissores errados com o mesmo cuidado do caminho válido.
Considerações
Defina fronteiras de token antes de escolher biblioteca. Documente quem emite, quais serviços verificam, audiências existentes e rotação de chaves. Use audiências diferentes para APIs com privilégios distintos. Configure exatamente o URI do emissor e valide-o de modo consistente. Se houver perfis diferentes, dê a cada um regra própria, em vez de uma regra permissiva que tenta adivinhar finalidade por claims opcionais.
Tempo exige cuidado operacional. Sincronize relógios de servidor, escolha tolerância pequena e documentada e observe falhas de deriva. Mantenha durações de access token proporcionais ao risco e desenhe renovação ou revogação fora do decodificador. Ver exp localmente ajuda a explicar falha, mas somente a política de tempo do verificador decide aceitação. Não assuma validade porque uma data parece recente em outro fuso.
Evite manter dados decodificados em estado de cliente desnecessário. A interface pode precisar de informação não sensível, mas o servidor deve ser autoridade para permissões e recursos protegidos. Quando um navegador armazena bearer token, a exposição depende do modelo de ameaça e armazenamento; decodificar não a diminui. Peça revisão de segurança ao desenhar uma fronteira de identidade.
Limitações
Este guia explica a fronteira conceitual entre decodificar e verificar. Não fornece configuração pronta de autenticação, desenho de gestão de chaves ou garantia de que uma biblioteca JWT seja segura se mal configurada. APIs, distribuição de chaves, perfis, armazenamento no navegador e requisitos de incidente variam por sistema. Leia a documentação atual do verificador e teste-o com emissor e audiência reais.
JWT não é obrigatório para toda sessão ou API. Tokens opacos, sessões de servidor e outros mecanismos têm compensações próprias. Uma assinatura válida também não prova que alguém está autorizado para toda ação, que um dispositivo está íntegro ou que um token não foi revogado por outro sistema. Considere verificação um controlo necessário dentro de um desenho mais amplo.
Lista de verificação
Antes de confiar num JWT, mantenha o token compacto original e separe inspeção de autorização. Decodifique cabeçalho e payload somente para diagnosticar estrutura; claims visíveis não são prova. Verifique assinatura num sistema confiável com lista de algoritmos e origem de chave autenticada. Exija emissor e audiência esperados, avalie expiração e not-before com política de tempo documentada e aplique autorização no servidor depois. Nunca publique ou registre bearer tokens reais, nunca desative verificação por conveniência e teste assinaturas e claims alteradas como casos negativos. Consulte RFC 7519 e RFC 8725 com a documentação atual da biblioteca.