Pular para o conteúdo
Categoria: Segurança da Informação12 min de leitura

O que é JWT (JSON Web Token)?

Por Schematize Blog ·

Entenda a estrutura, a assinatura e o uso correto de JWT para autenticacao stateless em APIs e apps, alem dos erros mais comuns e ataques que voce precisa evitar.

Se você já fez login em algum app construído com IA e reparou em uma string longa e estranha viajando entre o navegador e o servidor, há grandes chances de você ter visto um JWT. Esse formato virou o padrão de fato para representar identidade e permissões de forma compacta e verificável. Neste artigo você vai entender o que é um JSON Web Token, como ele é construído, quando faz sentido usá-lo e quais armadilhas derrubam aplicações reais.

O que é um JWT, afinal

Um JWT (JSON Web Token) é um formato padronizado para transportar informações entre duas partes de maneira compacta e segura, definido na RFC 7519 (Jones, Bradley, Sakimura, 2015). Na prática, é uma string de texto que carrega um conjunto de dados em formato JSON — chamados de claims — junto com uma assinatura que permite verificar se o conteúdo não foi adulterado.

A ideia central é simples: em vez de o servidor guardar o estado da sessão em memória ou banco, ele entrega ao cliente um token que carrega a própria identidade do usuário. Quando o cliente faz uma nova requisição, ele envia esse token de volta, e o servidor apenas verifica a assinatura para confiar no conteúdo. Por isso dizemos que o JWT habilita autenticação stateless (sem estado no servidor).

Antes de seguir, vale fixar uma distinção fundamental: um JWT geralmente prova quem você é, mas o que você pode fazer é uma decisão à parte. Se essa fronteira ainda está nebulosa, vale ler Autenticação vs autorização: qual a diferença?, porque ela explica por que um token válido não é um cheque em branco.

O JWT é apenas o conteúdo. A "embalagem" criptográfica que envolve esse conteúdo é definida por padrões irmãos: o JWS (JSON Web Signature, RFC 7515) cuida de assinar, e o JWE (JSON Web Encryption) cuida de criptografar. Na imensa maioria dos casos, quando alguém fala "JWT", está se referindo a um JWS — um token assinado, mas não criptografado. Guardar essa diferença ajuda a entender por que o conteúdo é público por padrão.

A anatomia de um JWT: três partes

Um JWT é formado por três blocos separados por pontos:

xxxxx.yyyyy.zzzzz

Esses três blocos são, na ordem: header (cabeçalho), payload (carga útil) e signature (assinatura). Cada um dos dois primeiros é um objeto JSON codificado em Base64URL — uma variação do Base64 segura para uso em URLs. É importante entender que Base64 não é criptografia: qualquer pessoa pode decodificar e ler o conteúdo. O que protege o token é a assinatura, não o embaralhamento.

O header

O cabeçalho descreve o tipo do token e o algoritmo usado na assinatura:

{
  "alg": "HS256",
  "typ": "JWT"
}

Aqui alg indica o algoritmo (por exemplo, HS256 para HMAC com SHA-256) e typ confirma que é um JWT. Em sistemas que usam chaves assimétricas e rotacionam chaves, é comum aparecer também um campo kid (key ID), que diz qual chave pública deve ser usada para verificar aquele token específico.

O payload

O payload guarda os claims, que são afirmações sobre o usuário ou sobre o próprio token:

{
  "sub": "1234567890",
  "name": "Ana Souza",
  "role": "editor",
  "iat": 1716200000,
  "exp": 1716203600
}

A RFC 7519 define um conjunto de claims registrados que você deveria conhecer:

    Além desses, você pode adicionar claims customizados como role ou email. Lembre-se: como o payload é apenas codificado, nunca coloque dados sensíveis ali (senhas, números de cartão, segredos).

    Um detalhe que decorre disso e pega muita gente: autorização não deve viver inteiramente no token. Como o JWT é emitido em um momento e usado depois, qualquer permissão que você "congele" dentro dele pode ficar desatualizada. Se um usuário é rebaixado de admin para editor, um token antigo ainda dirá admin até expirar. Por isso, decisões de autorização sensíveis costumam ser resolvidas ao vivo no servidor, não lidas cegamente de um claim.

    A assinatura

    A assinatura é o que dá confiança ao token. Ela é gerada aplicando o algoritmo do header sobre o header e o payload codificados, usando uma chave secreta:

    HMACSHA256(
      base64UrlEncode(header) + "." + base64UrlEncode(payload),
      segredo
    )

    Se alguém alterar um único caractere do payload — por exemplo, trocar "role": "editor" por "role": "admin" — a assinatura deixa de bater e o servidor rejeita o token. Para entender por baixo dos panos como funciona esse tipo de função, vale a leitura de O que é criptografia? Simétrica, assimétrica e hashing.

    Como a assinatura realmente protege o token

    Existem duas grandes famílias de algoritmos de assinatura para JWT:

        A escolha entre simétrico e assimétrico tem implicações de segurança importantes, e novamente o artigo sobre O que é criptografia? Simétrica, assimétrica e hashing aprofunda essa diferença.

        Na prática, sistemas que usam chaves assimétricas costumam expor as chaves públicas em um endpoint padronizado chamado JWKS (JSON Web Key Set). O serviço que valida tokens busca esse conjunto de chaves, encontra a chave certa pelo kid do header e verifica a assinatura — tudo sem nunca conhecer a chave privada. Isso é o que permite rotacionar chaves sem reimplantar todos os serviços de uma vez.

        O ciclo de vida: login, uso e expiração

        O fluxo típico de uso de JWT em um app web ou mobile costuma ser assim:

          GET /api/perfil HTTP/1.1
          Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

            Como o token tem vida curta por segurança, costuma-se usar um refresh token de vida mais longa, guardado com mais cuidado, para obter novos JWTs sem forçar o usuário a logar de novo. O JWT é também a peça que circula em protocolos de delegação como o descrito em O que é OAuth 2.0? Delegação de acesso explicada, onde tokens representam permissões concedidas a aplicativos terceiros.

            Access token vs refresh token

            Vale separar bem os papéis dos dois tokens, porque confundi-los gera furos de segurança:

              Esse desenho de "token curto sem estado + token longo com estado" é o que a maioria das aplicações sérias adota, porque combina a escalabilidade do JWT com a capacidade de revogação que ele sozinho não tem.

              JWT vs sessões tradicionais

              Vale comparar os dois modelos para entender quando cada um brilha:

              | Aspecto | Sessão no servidor | JWT (stateless) | |---|---|---| | Onde fica o estado | Banco/memória do servidor | No próprio token, com o cliente | | Escalabilidade horizontal | Exige sessão compartilhada | Natural — qualquer instância verifica | | Revogação imediata | Fácil (apaga a sessão) | Difícil (token vale até expirar) | | Tamanho da requisição | Pequeno (só o ID) | Maior (token inteiro vai junto) |

              O ponto sobre revogação é o calcanhar de Aquiles do JWT: como o servidor não guarda estado, ele não consegue, por padrão, invalidar um token antes do exp. Estratégias comuns para mitigar isso incluem listas de bloqueio (denylist) de tokens, tempos de expiração curtos e rotação de chaves de assinatura.

              Um esclarecimento útil: JWT não é "melhor" que sessão de servidor — são escolhas com trade-offs diferentes. Sessões tradicionais continuam excelentes para um app monolítico onde revogação instantânea importa muito. O JWT brilha quando você tem múltiplos serviços, precisa escalar horizontalmente ou quer que terceiros validem identidade sem chamar de volta o servidor de autenticação a cada requisição.

              Erros comuns que você deve evitar

              Muitos incidentes de segurança com JWT vêm de implementações descuidadas. Os mais perigosos:

                O ataque de confusão de algoritmo, em detalhe

                Por ser o mais sutil, o ataque de "algorithm confusion" merece um exemplo. Imagine um serviço que verifica tokens RS256 usando a chave pública — que, por definição, é conhecida por todos. Se o código de verificação for ingênuo e simplesmente "ler o alg do header e usar a chave configurada", um atacante pode:

                  Se o servidor usar a mesma chave para verificar tanto RSA quanto HMAC, a assinatura "bate" e o token forjado é aceito — com qualquer claim que o atacante quiser, inclusive "role": "admin". A defesa é direta: nunca deixe o token escolher o algoritmo. Configure a verificação para aceitar exatamente um algoritmo esperado e rejeite todo o resto.

                  // pseudocódigo da verificação segura
                  verificar(token, {
                    algoritmosPermitidos: ["RS256"],   // lista fixa, nunca lida do header
                    audiencia: "minha-api",
                    emissor: "https://auth.exemplo.com"
                  })

                  JWT no contexto de APIs

                  Quando você constrói uma API que será consumida por front-ends, apps móveis ou outros serviços, o JWT se encaixa muito bem porque cada requisição carrega sua própria prova de identidade. Ainda assim, o token é apenas uma peça de um conjunto maior de defesas. Para ver como ele se combina com rate limiting, validação de entrada e outras camadas, vale o aprofundamento em Segurança de APIs: protegendo seus endpoints.

                  Um bom hábito é tratar a verificação do JWT como um middleware central: um único ponto que valida assinatura e claims antes de qualquer rota protegida ser executada. Isso evita o erro recorrente de proteger algumas rotas e esquecer outras.

                  Perguntas frequentes

                  JWT é criptografado? Por padrão, não. O JWT mais comum é assinado (JWS), o que garante integridade, mas o conteúdo é apenas codificado em Base64URL e pode ser lido por qualquer um. Para confidencialidade real do conteúdo, é preciso usar JWE.

                  Posso invalidar um JWT antes de ele expirar? Não diretamente, porque ele é stateless. Você mitiga isso com expiração curta, uma denylist de tokens revogados ou apoiando a revogação no refresh token, que é rastreado no servidor.

                  Onde devo guardar o JWT no navegador? Cookies HttpOnly e Secure reduzem o risco de roubo via XSS, mas exigem cuidado com CSRF. localStorage é mais simples, porém vulnerável a XSS. Não existe opção perfeita; a escolha depende do modelo de ameaça da aplicação.

                  Qual deve ser o tempo de expiração? Para access tokens, minutos (5 a 15 é comum). A vida longa fica por conta do refresh token, que pode durar dias ou semanas, mas com revogação possível.

                  Conclusão

                  O JWT é um formato elegante para transportar identidade de forma compacta, verificável e sem estado no servidor, o que o torna ideal para APIs e arquiteturas distribuídas. Sua força está na assinatura criptográfica, não no embaralhamento — por isso o conteúdo é público e nunca deve guardar segredos. Use expiração curta, valide todos os claims relevantes, fixe os algoritmos aceitos, apoie a revogação em refresh tokens e tenha uma estratégia clara para quando precisar invalidar acessos. Dominando essas práticas, você aproveita o melhor do JWT sem cair nas armadilhas que comprometem aplicações reais.

                  Referências

                    Leituras relacionadas

                    Nenhum comentário ainda

                    Seja o primeiro a comentar.

                    Deixe seu comentário

                    Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

                    Entrar com Canverly