O que é um JSON Web Token (JWT)?

Atualizado em: agosto de 2026

Um JSON Web Token é um token compacto e seguro para URLs que carrega claims JSON assinadas, permitindo verificar requisições sem sessões no servidor. Esse é o enquadramento da própria RFC 7519 — “um meio compacto e seguro para URLs de representar claims a serem transferidas entre duas partes” — e as duas ideias contidas nele carregam tudo o que vem a seguir: o token contém seus fatos, e uma assinatura torna esses fatos verificáveis por qualquer um que tenha a chave certa, sem banco de dados no caminho.

Principais pontos

PerguntaResposta
O formatoheader.payload.signature — três partes Base64Url unidas por pontos
O truqueQualquer um pode decodificar; só quem tem a chave pode forjar
Não é criptografiaO payload é legível — assinado ≠ secreto (isso é trabalho do JWE)
A trocaVerificação stateless ↔ nenhuma revogação nativa até o exp
A disciplinaFixe algoritmos · valide iss/aud/exp · vidas curtas + rotação de refresh tokens

Um JWT, decodificado

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJzdWIiOiJ1c3ItOGZrMiIsInJvbGUi… . dBjftJeZ4CVP…

header     { "alg": "HS256", "typ": "JWT" }
payload    { "sub": "usr-8fk2",  "role": "editor",
             "iss": "https://api.example.com",  "aud": "example-web",
             "iat": 1767024900,  "exp": 1767025800 }        ← vida de 15 minutos
signature  HMACSHA256( base64url(header) + "." + base64url(payload), secret )

Qualquer um pode DECODIFICAR as duas primeiras partes — Base64Url é empacotamento, não criptografia.
Só quem tem a chave consegue FORJAR a terceira — e esse é o truque inteiro.

O contraste que vale ver em código — a alternativa stateful contra a qual toda decisão de JWT é medida:

// JavaScript / Node.js — Back4app JS SDK
// The stateful contrast: Back4app issues revocable session tokens
const user = await Parse.User.logIn('ada', 'correct-horse-battery');
const token = user.getSessionToken(); // r:abc123… — opaque, server-side state
// Every request presents it; the server can revoke it instantly:
await Parse.User.logOut(); // token invalid NOW — no waiting for an exp claim

Como a verificação funciona

Fluxo de emissão e verificação de JWTNo login, o servidor assina um token contendo claims e o devolve ao cliente. O cliente o armazena e o envia como bearer token em cada requisição. O servidor verifica a assinatura com sua chave e valida as claims, aceitando ou rejeitando sem nenhuma consulta de sessão.

Authorization: Bearer eyJ…

válido

adulterado / expirado / aud errada

Login
(credenciais verificadas uma vez)

Servidor assina o JWT
claims + chave

Cliente guarda o token

Qualquer servidor com a chave:
verifica a assinatura · valida as claims

Requisição prossegue
sem consulta de sessão

401

No login, o servidor assina um token contendo claims e o devolve ao cliente. O cliente o armazena e o envia como bearer token em cada requisição. O servidor verifica a assinatura com sua chave e valida as claims, aceitando ou rejeitando sem nenhuma consulta de sessão.

Uma precisão que os explicadores pulam: “JWT” nomeia o formato das claims; o que todo mundo de fato passa adiante é um JWS (RFC 7515) — a serialização assinada — enquanto o JWE é o irmão criptografado, para payloads que precisam permanecer ilegíveis. E a verificação são dois trabalhos, não um: checar a assinatura e depois validar as claimsexp e nbf contra o relógio, iss contra sua lista de emissores confiáveis, aud contra o identificador deste serviço. Um token perfeitamente assinado que está expirado, veio do emissor errado ou foi cunhado para outra audiência é um ataque perfeitamente assinado.

Claims: o vocabulário do payload

ClaimNomeTrabalho do verificador
issEmissor (issuer)Este é um emissor em que eu confio?
subSujeito (subject)De quem se trata — o ID estável do usuário
audAudiência (audience)Foi cunhado para mim? Rejeite tokens alheios
expExpiraçãoRejeite após este timestamp Unix
iat / nbfEmitido em / não antes deConfira a sanidade da janela de validade
jtiID do tokenIdentificador único — o gancho de que uma denylist precisa
customPapéis, tenant, plano…Semântica do app — mínimo possível, nunca segredos

Mantenha os payloads enxutos por dois motivos: os tokens viajam em toda requisição como headers (cookies estouram perto de 4 KB, e cada claim é banda repetida), e tudo neles é legível para quem tiver o token.

JWT vs. session tokens

JWT (stateless)Session token (stateful)
O token éO próprio estado, assinadoUm ponteiro opaco para estado no servidor
Custo por requisiçãoVerificação de assinatura, sem consultaUma consulta ao session store
RevogaçãoNenhuma até o exp — por designInstantânea — apague a session
Auth entre serviçosQualquer serviço com a chave verificaOs serviços precisam compartilhar o session store
Logout significaO cliente descarta; o token segue válidoO token morre de verdade
Melhor casaAPIs, microsserviços, verificação por terceirosApps de backend único, sessões sensíveis

A verdade fora de moda com que vários guias de boas práticas agora abrem: para um app renderizado no servidor com um único backend, as sessions do framework são mais simples e mais controláveis — JWTs pagam o próprio custo quando os tokens precisam ser verificados entre serviços ou por partes que não deveriam telefonar para casa a cada requisição.

O problema da revogação, com honestidade

Ser stateless é ser incapaz de revogar — a mesma propriedade, descrita duas vezes. Um token assinado é válido até o exp não importa o que tenha acontecido desde então: logout, troca de senha, banimento da conta. Toda correção reintroduz estado, então escolha o sabor: uma denylist indexada por jti + iss (a construção recomendada pela OWASP) checada a cada requisição — estado pequeno, mas estado; versionamento de chaves, que revoga todo mundo de uma vez; ou a arquitetura padrão — access tokens de vida curta (5–15 minutos) mais refresh tokens revogáveis com rotação: cada refresh emite um novo refresh token e aposenta o anterior, então um token roubado morre no primeiro replay, e o reúso de um token aposentado sinaliza o roubo e mata a família inteira de tokens. A latência de revogação passa a ser igual à vida do access token — que é a verdadeira razão de essas vidas serem curtas.

Escolhendo o algoritmo — e os ataques contra a escolha

HS256 (HMAC)RS256 (RSA)EdDSA / ES256
ChavesUm secret compartilhadoA privada assina, a pública verificaA privada assina, a pública verifica
Verificadores precisamDo secret (que também forja!)Só da chave públicaSó da chave pública
Serve paraEmissor = verificador, uma só parteMultisserviço, terceirosIdem, assinaturas menores e mais rápidas
Aresta afiadaSecrets curtos sofrem brute force offline a partir de um único token capturado — use ≥256 bits aleatóriosTokens maiores, mais lentoSuporte de biblioteca mais recente

A seção de ataques para a qual a RFC 8725 existe, em três frases. alg: "none" é um valor legal de header — bibliotecas que o honram aceitam tokens sem assinatura. O ataque de confusão: um verificador que deixa o header do token escolher o algoritmo pode receber um token “HS256” assinado com a chave RSA pública do servidor usada como secret do HMAC — um valor público usado como privado. Os dois morrem do mesmo jeito: o verificador fixa em configuração os algoritmos e as chaves que aceita e nunca confia no header para escolher.

Onde armazenar JWTs no navegador

LocalXSS rouba?CSRF envia?Sobrevive ao refresh da página?Veredito
localStorageSimNãoSimEvite — legível por script
Cookie comumSim (legível por script)SimSimO pior dos dois mundos
Cookie HttpOnly + Secure + SameSiteNãoMitigado pelo SameSiteSimBom — para o refresh token
Em memóriaSó enquanto o script injetado viveNãoNãoBom — para o access token
Backend-for-frontend guarda os tokensO navegador nunca os temValem as regras de cookieSimO mais forte para SPAs

O modelo de ameaça, não o folclore: localStorage troca imunidade a CSRF por roubo via XSS, cookies trocam o inverso — e é por isso que o consenso divide o par: access token em memória, refresh token em um cookie endurecido.

Casos de uso comuns

  • Autenticação de APIs — o bearer token por trás dos headers Authorization em APIs REST e GraphQL.
  • Identidade em microsserviços — um token emitido pelo gateway e verificado de forma independente por cada serviço, sem session store compartilhado.
  • ID tokens do OpenID Connect — a asserção de identidade assinada em todo login social — sempre um JWT.
  • Handoffs entre sistemas — links assinados, payloads de webhook, concessões de download: claims verificadas por uma parte que não pode te chamar de volta.
  • Dicas de autorização stateless — papéis e IDs de tenant carregados em claims, com a verificação autoritativa ainda no servidor.

JWTs ou sessions? Matriz de decisão

Sua situaçãoEscolha
Backend único, app renderizado no servidorSessions — mais simples, revogáveis na hora
API pública consumida por muitos serviçosJWTs, chaves assimétricas
Microsserviços atrás de um gatewayJWTs — verificação local, sem store compartilhado
Bloqueio instantâneo é requisito inegociávelSessions, ou JWTs + denylist e exp curto
Terceiros precisam verificar suas asserçõesJWTs — o jogo em casa do formato
App mobile contra um BaaSO mecanismo de session da plataforma — ela já escolheu

Limitações e trade-offs

  • A irrevogabilidade é estrutural. Toda mitigação — denylists, vidas curtas, rotação — é uma devolução parcial do estado que você removeu; precifique isso antes de escolher stateless.
  • Claims envelhecem. Os papéis são um snapshot da emissão; um admin rebaixado continua admin até expirar. Vidas curtas limitam a janela de defasagem.
  • O payload é público. Trate-o como legível pelo usuário e por qualquer ladrão de token — identificadores sim, segredos e PII não.
  • Defaults de biblioteca já queimaram muita gente. Fixar algoritmos, validar claims e checar o typ são responsabilidades da sua configuração, não garantias da biblioteca.
  • O tamanho se acumula. Cada claim viaja em cada requisição; payloads generosos taxam a banda mobile e podem estourar os limites de cookie.

Tokens no Back4app

O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. A escolha da própria plataforma ilustra a matriz de decisão: as sessões de cliente usam session tokens revogáveis, mantidos no servidor — as abas de código acima — então logout, trocas de senha e o encerramento de sessões pelo dashboard têm efeito imediato, sem janela de expiração para esperar. JWTs aparecem onde pertencem: os ID tokens OIDC dos provedores de identidade são verificados no servidor pelos adaptadores de auth durante o login social, e funções de Cloud Code podem cunhar ou verificar JWTs para handoffs com terceiros usando bibliotecas padrão — com o secret de assinatura na configuração do servidor, nunca enviado aos clientes. Stateful onde o controle importa, stateless nas bordas onde a verificação precisa viajar: a arquitetura que este artigo defende, já montada.

Perguntas frequentes

O que é um JWT em termos simples?

Uma "carteira de identidade" em JSON, assinada e codificada em Base64, que o servidor emite no login. O cliente a apresenta em cada requisição, e o servidor verifica a assinatura em vez de consultar uma sessão — o próprio token carrega quem você é e até quando. Oficialmente, a pronúncia rima com "jot", segundo a RFC que o define.

Quais são as três partes de um JWT?

Header (tipo do token e algoritmo de assinatura), payload (as claims — os dados JSON de fato) e assinatura, cada parte codificada em Base64Url e unida por pontos em header.payload.signature. A assinatura é computada sobre as duas primeiras partes, então qualquer adulteração nelas quebra a verificação.

O JWT é criptografado?

Não — codificado, não criptografado. Base64Url é um formato de transporte que qualquer um reverte; cole qualquer JWT em um decodificador e o payload fica legível. A assinatura impede adulteração, não leitura. Nunca coloque segredos ou dados pessoais sensíveis no payload de um JWT; a variante criptografada (JWE) existe para necessidades reais de confidencialidade.

Qual a diferença entre JWT e session token?

Onde o estado mora. Um session token é um ID opaco apontando para estado no servidor — uma consulta por requisição, revogável na hora. Um JWT carrega o estado dentro de si — sem consulta, verificável por qualquer serviço que tenha a chave, mas válido até expirar, aconteça o que acontecer. Escala stateless versus controle instantâneo.

Onde devo armazenar um JWT no navegador?

Não no localStorage — qualquer script injetado consegue lê-lo, transformando XSS em roubo de token. O consenso atual: mantenha o access token em memória, o refresh token em um cookie HttpOnly, Secure e SameSite, e considere o padrão backend-for-frontend, que mantém os tokens totalmente fora do navegador.

Um JWT pode ser revogado?

Não por design — um token assinado vale até a claim exp, o que é o preço do stateless. Os contornos reintroduzem estado: uma denylist indexada pela claim jti, chaves versionadas ou — a resposta padrão — access tokens de vida bem curta emparelhados com refresh tokens revogáveis e rotacionados.

JWT é seguro?

O formato é sólido; as implementações falham. Os buracos clássicos: aceitar alg none, deixar o header do token escolher o algoritmo (o ataque de confusão de RS256 para HS256), secrets HMAC curtos vulneráveis a brute force e pular a validação de aud/iss/exp. Fixe seus algoritmos, valide toda claim, mantenha vidas curtas.

Qual a diferença entre JWT e OAuth?

Categorias diferentes: JWT é um formato de token; OAuth 2.0 é um framework de autorização. Eles se compõem — fluxos OAuth costumam emitir access tokens que por acaso são JWTs, e os ID tokens do OpenID Connect sempre são. Um diz como o token é construído; o outro, como os tokens são distribuídos.

Termos relacionados

Compare com

Leitura adicional

Pronto para construir seu backend?

Comece seu projeto no Back4app em minutos — banco de dados, autenticação, APIs e Cloud Code incluídos. Sem cartão de crédito.

Escrito e revisado por Back4app Engineering, Back4app Engineering · Publicado em 2026-08-20