6 min

O que é JWT? Um guia claro sobre JSON Web Tokens

Entenda o que é um JWT (JSON Web Token), como suas três partes funcionam, onde é usado e as principais dicas de segurança para evitar erros comuns.

O que é JWT? Um guia claro sobre JSON Web Tokens

JWT em termos simples

Um JWT (JSON Web Token) é uma string compacta e segura para URLs que representa um conjunto de informações (normalmente sobre um usuário ou sessão) de forma a poder ser passada entre sistemas. Você frequentemente o verá como um valor longo começando por algo como eyJ..., enviado em um cabeçalho HTTP como Authorization: Bearer <token>.

Por que usar um token?

Logins tradicionais muitas vezes dependem de sessões no servidor: depois de fazer login, o servidor armazena dados de sessão e fornece ao navegador um cookie de ID de sessão. Cada requisição inclui esse cookie e o servidor consulta a sessão.

Com autenticação baseada em tokens, o servidor pode evitar manter estado de sessão para cada requisição do usuário. Em vez disso, o cliente guarda um token (como um JWT) e o inclui nas chamadas à API. Isso é popular em APIs porque:

  • funciona bem entre vários serviços (API gateways, microsserviços)
  • se adapta a apps móveis e SPAs que chamam APIs diretamente
  • reduz a necessidade de armazenamento de sessão compartilhado entre servidores

Nuance importante: “sem estado” não significa “sem verificações no servidor”. Muitos sistemas reais ainda validam tokens contra o status do usuário, rotação de chaves ou mecanismos de revogação.

Autenticação vs autorização (em linguagem simples)

  • Autenticação responde: Quem é você? (Você faz login e prova sua identidade.)
  • Autorização responde: O que você pode fazer? (Ler faturas, editar projetos, acessar páginas de admin, etc.)

JWTs comumente carregam prova de autenticação (você está autenticado) e dicas básicas de autorização (roles, permissões, scopes)—mas seu servidor ainda deve aplicar as regras de autorização.

Onde os JWTs aparecem

Você verá JWTs usados com frequência como tokens de acesso em:

  • APIs web
  • SPAs
  • apps móveis
  • sistemas que usam OAuth 2.0 ou OpenID Connect (OIDC)

Estrutura do JWT: header, payload e signature

Um JWT é uma string compacta feita de três partes, cada uma codificada em base64url e separadas por pontos:

header.payload.signature

Exemplo (redigido):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNzAwMDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c…

1) Header

O header descreve como o token foi criado—mais importante, o algoritmo de assinatura (por exemplo, HS256, RS256/ES256) e o tipo do token.

Campos comuns:

  • typ: frequentemente "JWT" (muitas vezes ignorado na prática)
  • alg: o algoritmo de assinatura usado
  • kid: identificador de chave para ajudar o verificador a selecionar a chave correta durante rotação

Nota de segurança: não confie no header cegamente. Aplique uma allowlist de algoritmos que você realmente usa e não aceite alg: "none".

2) Payload

O payload contém “claims” (campos) sobre o usuário e o contexto do token: para quem é, quem o emitiu e quando expira.

Importante: JWTs não são criptografados por padrão. A codificação Base64URL torna o token seguro para URLs; ela não oculta os dados. Qualquer pessoa que obtenha o token pode decodificar header e payload.

Por isso evite colocar segredos (senhas, chaves de API) ou dados pessoais sensíveis dentro de um JWT.

3) Signature

A assinatura é criada assinando o header + payload com uma chave:

  • HS256: um segredo compartilhado assina e verifica
  • RS256/ES256: uma chave privada assina; uma chave pública verifica

A assinatura fornece integridade: permite ao servidor verificar que o token não foi modificado e foi emitido por um assinador confiável. Ela não fornece confidencialidade.

Considerações de tamanho

Como um JWT inclui header e payload em cada requisição onde é enviado, tokens maiores significam mais largura de banda e overhead. Mantenha os claims enxutos e prefira identificadores a dados volumosos.

Payload e claims: o que você pode (e não deve) armazenar

Implemente autenticação JWT mais rápido
Construa uma aplicação protegida por JWT conversando e depois refine as regras de verificação no modo de planejamento.

Claims geralmente caem em duas categorias: registrados (nomes padronizados) e customizados (campos do seu app).

Claims registrados comuns

  • iss (issuer): quem criou o token
  • sub (subject): quem é o assunto do token (frequentemente um ID de usuário)
  • aud (audience): para quem o token é destinado (ex.: uma API específica)
  • exp (expiration time): quando o token deve parar de ser aceito
  • iat (issued at): quando o token foi criado
  • nbf (not before): o token não deve ser aceito antes desse momento

Claims customizados: mantenha mínimos

Inclua apenas o que o serviço receptor realmente precisa para tomar uma decisão de autorização.

Bons exemplos:

  • um identificador interno estável do usuário (user_id)
  • um conjunto pequeno de roles/permissões (somente se você conseguir mantê-los atualizados)
  • um ID de tenant/organização em apps multi-tenant

Evite “claims de conveniência” que duplicam muitos dados de perfil. Eles incham o token, ficam rapidamente desatualizados e aumentam o impacto em caso de vazamento.

O que você nunca deve colocar no payload de um JWT

Como o payload é legível, não armazene:

  • senhas, chaves de API, refresh tokens ou qualquer valor secreto
  • dados de pagamento, documentos governamentais ou dados pessoais sensíveis
  • qualquer coisa que você não queira copiada de um navegador, proxy ou log

Se precisar de informação sensível, armazene-a no servidor e coloque apenas uma referência (como um ID) no token—ou use um formato de token criptografado (JWE) quando apropriado.

Como a assinatura funciona (e o que ela garante)

Assinar não é criptografar.

  • Assinar é como lacrar uma carta: as pessoas podem ler, mas podem verificar que não foi alterada.
  • Criptografar é como trancar a carta em uma caixa: apenas quem tem a chave pode ler.

Quando um JWT é emitido, o servidor assina o header + payload codificados. Quando o token é apresentado depois, o servidor recalcula a assinatura e a compara. Se alguém alterar mesmo um caractere (ex.: "role":"user" para "role":"admin"), a verificação falha e o token é rejeitado.

JWT vs OAuth, OpenID Connect e tipos de token

JWT é um formato de token. OAuth 2.0 e OpenID Connect (OIDC) são protocolos que descrevem como apps solicitam, emitem e usam tokens.

OAuth 2.0 e access/refresh tokens

OAuth 2.0 trata principalmente de autorização: permitir que um app acesse uma API em nome de um usuário sem compartilhar a senha do usuário.

  • Access token: apresentado a uma API para provar permissão; pode ser um JWT ou um token opaco
  • Refresh token: token de vida mais longa usado para obter novos access tokens

Access tokens são tipicamente de curta duração (minutos). Vidas curtas limitam o dano se um token vazar.

OpenID Connect (OIDC) e ID tokens

OIDC adiciona autenticação (quem é o usuário) em cima do OAuth 2.0 e introduz um ID token, que geralmente é um JWT.

  • ID token: para o cliente confirmar a identidade do usuário
  • Access token: para a API autorizar requisições

Uma regra chave: não use um ID token para chamar uma API.

Se quiser mais contexto sobre fluxos práticos, veja /blog/jwt-authentication-flow.

Fluxo comum de autenticação com JWT

Ganhe mais créditos de build
Compartilhe o que construiu com a Koder.ai ou convide colegas e ganhe créditos conforme avança.

Um fluxo típico se parece com isto:

1) Login

O usuário faz login (email/senha, SSO, etc.). Se for bem-sucedido, o servidor cria um JWT (frequentemente um access token) com claims essenciais como subject e expiração.

2) Emissão do token

O servidor assina o token e o retorna ao cliente (app web, app móvel ou outro serviço).

3) Chamadas à API

Para endpoints protegidos, o cliente inclui o JWT no cabeçalho Authorization:

Authorization: Bearer <JWT>

4) Verificação

Antes de atender a requisição, a API normalmente checa:

  • assinatura (integridade + emissor confiável)
  • exp (não expirado)
  • iss (issuer esperado)
  • aud (destinado a esta API)

Se todas as checagens passarem, a API considera o usuário autenticado e aplica as regras de autorização (ex.: permissões ao nível de registro).

5) Nota rápida sobre drift de relógio

Como relógios de sistema variam, muitos sistemas permitem um pequeno clock skew ao validar claims baseados em tempo como exp (e às vezes nbf). Mantenha o skew pequeno para evitar estender a validade do token além do pretendido.

Onde armazenar JWTs de forma segura

As escolhas de armazenamento mudam o que um atacante pode roubar e quão facilmente podem reproduzir um token.

Apps em navegador: memória vs localStorage vs cookies

Armazenamento em memória (frequentemente recomendado para SPAs) guarda o access token no estado JS. É limpo ao atualizar a página e reduz o risco de “pegar depois”, mas um bug XSS ainda pode lê-lo enquanto a página está ativa. Combine com tokens de curta duração e um fluxo de refresh.

localStorage/sessionStorage são fáceis, mas arriscados: qualquer vulnerabilidade XSS pode exfiltrar tokens do armazenamento web. Se usá-los, trate prevenção de XSS como imprescindível (CSP, escape de saída, higiene de dependências) e mantenha tokens de curta duração.

Cookies seguros (geralmente o padrão mais seguro para web) armazenam tokens em um cookie HttpOnly para que o JavaScript não possa lê-los—reduzindo o impacto do roubo via XSS. A troca é o risco de CSRF, já que os navegadores anexam cookies automaticamente.

Se usar cookies, configure:

  • HttpOnly
  • Secure (apenas HTTPS)
  • SameSite=Lax ou SameSite=Strict (alguns fluxos cross-site podem precisar de SameSite=None; Secure)

Considere também tokens CSRF para requisições que mudam estado.

Apps móveis: prefira armazenamento seguro do SO

No iOS/Android, armazene tokens no armazenamento seguro da plataforma (Keychain / armazenamento com suporte a Keystore). Evite arquivos simples ou preferências. Se seu modelo de ameaça inclui dispositivos com root/jailbreak, assuma extração possível e dependa de tokens de curta duração e controles no servidor.

Princípio do menor privilégio

Limite o que um token pode fazer: use scopes/claims mínimos, mantenha tokens de acesso de curta duração e evite embutir dados sensíveis.

Armadilhas comuns de segurança com JWT a evitar

JWTs são convenientes, mas muitos incidentes surgem de erros previsíveis. Trate um JWT como dinheiro: quem o obtém normalmente pode gastá-lo.

1) Expirações muito longas

Se um token dura dias ou semanas, um vazamento dá ao atacante essa janela inteira.

Prefira access tokens de curta duração (minutos) e os renove por um mecanismo mais seguro. Se precisar de “lembrar-me”, faça isso com refresh tokens e controles server-side.

2) Pular checagens de issuer e audience

Assinaturas válidas não são suficientes. Verifique iss e aud, e valide claims baseados em tempo como exp e nbf.

3) Confiar no payload decodificado

Decodificar não é verificar. Sempre valide a assinatura no servidor e aplique permissões server-side.

4) Confusão de algoritmo e chaves

  • Não aceite qualquer algoritmo que o token declare. Use uma allowlist de algoritmos esperados.
  • Não confunda chaves simétricas (HS256) com chaves assimétricas (RS256/ES256).
  • Minimize o blast radius separando chaves por ambiente e rotacionando-as.

5) Vazamento de tokens via URLs, logs e referers

Evite colocar JWTs em query params. Eles podem acabar no histórico do navegador, logs de servidores, ferramentas de analytics e cabeçalhos Referer.

Use Authorization: Bearer ... em vez disso.

6) Sem plano de rotação ou revogação de chaves

Assuma que chaves e tokens podem vazar. Rode chaves de assinatura, use kid para suportar rotação suave e tenha uma estratégia de revogação (expirações curtas + habilidade de desabilitar contas/sessões). Para orientação sobre armazenamento, veja /blog/where-to-store-jwts-safely.

Quando usar JWT (e quando não usar)

Itere com segurança na segurança
Teste mudanças na lógica de autenticação, depois crie um snapshot e reverta se algo quebrar.

JWTs são úteis, mas não são automaticamente a melhor escolha. A questão real é se você se beneficia de um token autocontido que pode ser verificado sem consultar o banco de dados em cada requisição.

Casos em que JWT se encaixa bem

  • APIs sem estado em escala: verificação local (assinatura + exp) sem consultas de sessão por requisição
  • Múltiplos serviços / microsserviços: regras de verificação compartilhadas e chaves públicas
  • SPAs e apps móveis: clientes chamando APIs diretamente
  • Tokens de acesso de curta duração: menor impacto em caso de roubo

Quando JWT é uma má escolha

  • Revogação instantânea é necessária: sessões são mais simples se você precisa de “logout em todo lugar agora” sem infraestrutura extra
  • Você precisa transportar dados sensíveis: JWTs típicos são assinados, não criptografados
  • Tokens de longa duração: são de alto valor e valem a pena serem roubados

Quando cookies de sessão simples são melhores

Para apps web server-rendered onde invalidação direta importa, sessões server-side com cookies HttpOnly muitas vezes são a opção mais simples e segura.

Checklist rápido para decisão

Escolha JWT se você precisa de verificação sem estado entre serviços e pode manter tokens de curta duração.

Evite JWT se precisar de revogação instantânea, planeja armazenar dados sensíveis no token ou pode usar cookies de sessão sem atrito.

Checklist prático e FAQs

Checklist de verificação (o que checar sempre)

  1. Assinatura válida

Verifique usando a chave correta e o algoritmo esperado. Rejeite assinaturas inválidas—sem exceções.

  1. exp (expiração)

Assegure que o token não expirou.

  1. nbf (not before)

Se presente, assegure que o token não está sendo usado antes do tempo.

  1. aud (audience)

Confirme que o token foi destinado à sua API/serviço.

  1. iss (issuer)

Confirme que o token veio do emissor esperado.

  1. Checagens de sanidade (recomendado)

Valide o formato do token, imponha tamanho máximo e rejeite tipos de claims inesperados para reduzir bugs em casos de borda.

Escolhendo HS256 vs RS256/ES256

  • HS256 (chave simétrica): um segredo compartilhado assina e verifica.

    • Bom para: um único app/API controlado por uma equipe.
    • Cuidado: qualquer verificador que tenha o segredo também pode forjar tokens.
  • RS256 / ES256 (chaves assimétricas): chave privada assina; chave pública verifica.

    • Bom para: múltiplos serviços verificando tokens; distribuir chaves públicas sem permitir assinatura.
    • Nota operacional: rotação é frequentemente mais segura porque apenas o assinador possui a chave privada.

Regra prática: se mais de um sistema independente precisa verificar tokens (ou você não confia totalmente em cada verificador), prefira RS256/ES256.

Monitoramento e logging (sem vazar tokens)

  • Não registre tokens brutos (headers, cookies, query strings).
  • Se precisar de correlação, registre uma impressão do token (ex.: hash) ou metadados seguros (iss, aud e um ID de usuário apenas se a política permitir).
  • Monitore anomalias: falhas de assinatura, picos de tokens expirados, audiencias/emissores incomuns e padrões suspeitos de refresh.

FAQs

O JWT é criptografado?

Não por padrão. A maioria dos JWTs é assinada, não criptografada, o que significa que o conteúdo pode ser lido por quem tem o token. Use JWE ou mantenha dados sensíveis fora dos JWTs.

Posso revogar um JWT?

Não facilmente se você depender apenas de tokens autocontidos. Abordagens comuns incluem tokens de acesso de curta duração, listas de negação para eventos de alto risco, ou refresh tokens com rotação.

Qual deve ser a duração do exp?

O mais curta possível sem prejudicar a UX e a arquitetura. Muitas APIs usam minutos para access tokens, combinados com refresh tokens para sessões mais longas.

Construindo apps protegidos por JWT mais rápido com Koder.ai

Se você está implementando autenticação JWT em uma nova API ou SPA, muito trabalho é repetitivo: configurar middleware, validar iss/aud/exp, ajustar flags de cookie e evitar que tokens apareçam em logs.

Com Koder.ai, você pode gerar código para um app web (React), serviços backend (Go + PostgreSQL) ou um app Flutter via um fluxo interativo—depois iterar em um modo de planejamento, usar snapshots e rollback enquanto refina a segurança, e exportar o código quando estiver pronto. É uma forma prática de acelerar a construção de fluxos de autenticação baseados em JWT mantendo controle sobre lógica de verificação, estratégia de rotação de chaves e configurações de deploy/hospedagem (incluindo domínios customizados).

Perguntas frequentes

O que é um JWT e onde eu normalmente o envio?

Um JWT (JSON Web Token) é uma string compacta e segura para URLs que carrega "claims" (campos de dados) e pode ser verificada por um servidor. É comumente enviado em requisições de API via:

  • Authorization: Bearer <token>

A ideia principal: o servidor pode validar a integridade do token (pela assinatura) sem precisar de um registro de sessão por usuário em cada requisição.

Como a autenticação com JWT difere das sessões no servidor?

A autenticação por sessão normalmente armazena estado no servidor (um registro de sessão referenciado por um cookie/ID de sessão). Com autenticação baseada em JWT, o cliente apresenta um token assinado a cada requisição e a API o valida.

JWTs são populares para APIs e arquiteturas multi-serviço porque a verificação pode ser feita localmente, reduzindo a necessidade de armazenamento de sessão compartilhado.

“Sem estado” ainda pode incluir verificações no servidor, como listas de revogação, checagens de status do usuário ou rotação de chaves.

Quais são as três partes de um JWT (header, payload, signature)?

Um JWT tem três partes codificadas em Base64URL separadas por pontos:

  • header.payload.signature

O header descreve como foi assinado, o payload contém claims (como sub, exp, aud) e a assinatura permite ao servidor detectar adulterações.

Um JWT é criptografado e as pessoas podem ler o que está dentro?

Não. JWTs padrão geralmente são assinados, não criptografados.

  • A assinatura prova integridade (não foi modificado) e autenticidade (emitido por um emissor confiável).
  • Qualquer pessoa que obtenha o token pode decodificar em Base64URL e ler header e payload.

Se precisar de confidencialidade, use JWE (tokens criptografados) ou mantenha dados sensíveis no servidor e coloque apenas um identificador no JWT.

O que a assinatura do JWT garante — e o que ela não garante?

A assinatura permite verificar que o token não foi alterado e foi gerado por quem possui a chave de assinatura.

Ela não garante:

  • ocultação do conteúdo do payload;
  • que o usuário ainda está ativo (a menos que você cheque isso);
  • revogação automática antes do exp.

Trate o token como uma credencial: se vazar, normalmente pode ser reutilizado até expirar.

O que significam `alg` e `kid` no header do JWT, e por que importam?

alg informa qual algoritmo foi usado (por exemplo, HS256 vs RS256). kid é um identificador de chave que ajuda a selecionar a chave certa durante rotação.

Regras de segurança:

  • Use uma allowlist de algoritmos esperados; não aceite valores arbitrários.
  • Nunca aceite alg: "none".
  • Não permita que um kid não confiável cause buscas inseguras por chaves.
Quais claims devo incluir no payload do JWT?

Comece com claims registrados padrão e mantenha claims customizados ao mínimo.

Claims comuns:

  • iss (issuer)
  • sub (subject / identificador do usuário)
  • aud (audience / API alvo)
  • exp (expiração)
  • iat (emitido em)
  • nbf (não antes)

Evite incluir segredos ou dados pessoais sensíveis no payload, pois eles ficam legíveis se o token for exposto.

Como JWT, OAuth 2.0 e OpenID Connect se relacionam (access tokens vs ID tokens)?

JWT é um formato de token; OAuth 2.0 e OpenID Connect são protocolos.

Mapeamento típico:

  • Access token: usado para chamar uma API (pode ser JWT ou opaco).
  • ID token (OIDC): usado pelo cliente para confirmar a identidade (geralmente um JWT).
  • Refresh token: usado para obter novos access tokens (freq. opaco; trate-o como altamente sensível).

Importante: não use um ID token para chamar uma API só porque ele “parece” um JWT de acesso.

Onde devo armazenar JWTs com segurança em um app de navegador?

Para apps web, opções comuns:

  • Em memória: reduz o risco de “roubar depois”, mas XSS ativo ainda pode ler o token. Combine com tokens de curta duração e fluxo de refresh.
  • localStorage/sessionStorage: conveniente, mas qualquer XSS pode exfiltrar tokens. Se usar, trate prevenção de XSS como obrigatória (CSP, escape de saída, higiene de dependências) e mantenha tokens curtos.
  • Cookies HttpOnly Secure: frequentemente o mais seguro para web, pois o JS não consegue ler; porém aumenta risco de CSRF porque o navegador anexa cookies automaticamente.

Se usar cookies, configure:

  • HttpOnly
  • Secure (apenas HTTPS)
  • SameSite=Lax ou SameSite=Strict (alguns fluxos cross-site podem precisar de SameSite=None; Secure)

Considere tokens anti-CSRF para requisições que mudam estado.

Quais verificações minha API deve fazer ao validar um JWT?

No mínimo, valide:

  • assinatura (com a chave correta e algoritmo allowlisted)
  • exp (não expirado)
  • iss (issuer esperado)
  • aud (destinado à sua API)
  • nbf (se presente)

Guardrails práticos:

  • impor tamanho máximo do token
  • rejeitar tipos de claims inesperados
  • permitir pequeno clock skew para lidar com deriva de relógio

Related posts