O que é JWT é por que ele está em todo lugar

TL;DR -- JWT resolve um problema pontual muito bem, mas virou solução padrão para tudo -- inclusive situacoes onde cria mais problemas do que resolve. Entenda quando usar é quando evitar.

JWT (JSON Web Token) é um formato de token compacto, assinado digitalmente, usado para transmitir informações entre partes de forma verificavel. A ideia é simples: o servidor gera um token com dados do usuario, assina com uma chave secreta é devolve ao cliente. Nas próximas requisicoes, o cliente envia esse token é o servidor valida a assinatura sem precisar consultar o banco de dados.

Esse mecanismo explodiu em popularidade por volta de 2015, quando APIs REST viraram padrão é a galera queria algo stateless -- sem precisar manter sessao no servidor. JWT parecia a solução perfeita: leve, portavel é fácil de implementar com bibliotecas prontas.

O problema é que a maioria dos tutoriais ensina JWT como se fosse a única forma de fazer autenticação em APIs. Isso criou uma geração de desenvolvedores que usa JWT em todo projeto sem questionar se é a escolha certa para aquele contexto.

Como JWT funciona por dentro

Um JWT é composto por tres partes separadas por ponto: header, payload é signature. O header específica o algoritmo de assinatura (geralmente HS256 ou RS256). O payload contem os claims -- dados como userId, email, exp (expiracao) é iat (emitido em). A signature é o hash criptografico das duas primeiras partes.

O ponto crucial: o payload é codificado em base64 mas não é criptografado. Qualquer pessoa com o token consegue ler o conteudo -- só não consegue falsificar a assinatura sem saber a chave. Então nunca coloque dados sensiveis no payload JWT.

O fluxo completo: usuario autentica com email/senha, servidor valida, gera o JWT assinado com a chave secreta é retorna. O cliente guarda o token é envia em cada requisicao no header Authorization: Bearer TOKEN. O servidor verifica a assinatura sem consultar banco -- esse é o beneficio stateless do JWT.

!
Atenção: base64 não é criptografia

Muitos devs acham que o JWT esconde os dados por estar em base64. Não esconde. Qualquer pessoa pode decodificar é ler o payload com uma linha de código. Nunca coloque senhas, tokens de API ou dados pessoais sensiveis no payload.

Os problemas reais do JWT que ninguém fala

O maior problema do JWT é a impossibilidade de revogacao imediata. Uma vez emitido, o token é valido até expirar -- ponto. Se o usuario fizer logout, trocar a senha, ou você precisar banir uma conta, o token antigo continua funcionando até o tempo de expiracao.

Como contorno, muitas equipes implementam blacklists de tokens revogados no banco ou Redis. Mas ai você perdeu o beneficio stateless que era o motivo de usar JWT em primeiro lugar. Você agora tem o pior dos dois mundos: a complexidade do JWT é a necessidade de consultar banco em toda requisicao.

  • Revogacao impossivel sem estado: logout real requer blacklist, que requer banco
  • Payload público: dados no token sao legiveis por qualquer um que interceptar
  • Tamanho maior: JWT tem 200-500 bytes vs 32 bytes de um session ID
  • Complexidade de refresh: tokens curtos precisam de refresh token, que adiciona outro fluxo
  • Vulnerabilidades históricas: algoritmo alg:none, confusao RS256/HS256, implementações bugadas
!
Vulnerabilidade clássica: algoritmo none

Em versões antigas de bibliotecas JWT, era possível enviar um token com alg:none é a biblioteca aceitava sem validar a assinatura. Sempre verifique que sua biblioteca ignora o campo alg do header é usa o algoritmo definido no servidor.

Como comecar: sessoes tradicionais é alternativas

Alternativas que você deveria conhecer

A alternativa mais simples é segura para a maioria das aplicações web é a sessao tradicional com cookie. O servidor gera um ID de sessao aleatorio, guarda no banco ou Redis, é devolve ao cliente via cookie HttpOnly é Secure. Em cada requisicao, o navegador envia o cookie automaticamente é o servidor valida o ID no banco.

Outra alternativa moderna é o Paseto (Platform-Agnostic Security Tokens) -- criado para corrigir os problemas de design do JWT. Paseto elimina o campo alg do header (que causou varias vulnerabilidades), usa apenas algoritmos seguros por padrão é tem uma API mais rigida que previne erros comuns de implementação.

Para sistemas distribuidos onde você realmente precisa de tokens stateless, o Token Opaco com introspeccao (padrão OAuth 2.0 RFC 7662) é uma boa escolha. O token é um ID aleatorio sem dados -- o servidor de recursos consulta o servidor de autorização para validar. Mais uma chamada de rede, mas revogacao imediata é sem payload exposto.

Exemplo prático: quando JWT faz é quando não faz sentido

Sem JWT: app web simples

Aplicação web monolitica com frontend React é backend Node.js no mesmo dominio. Sessao Redis + cookie HttpOnly/Secure é mais simples, com revogacao imediata é sem refresh token.

Com JWT: microservicos

Multiplos serviços precisam verificar autenticação sem consultar servidor central. JWT faz sentido aqui -- cada serviço valida a assinatura localmente sem chamada extra de rede.

JWT faz sentido quando você tem multiplos serviços que precisam verificar autenticação sem consultar um servidor central. Nesse caso, a assinatura criptografica é o valor real -- cada serviço valida localmente sem depender de rede interna.

Outro caso valido: tokens de curta duracao para operações específicas. Um link de redefinicao de senha com JWT de 15 minutos é prático é seguro -- não precisa de revogacao porque expira rapido.

!
Regra prática

Se você precisa revogar o token antes da expiracao (logout, troca de senha, banimento), você precisara de estado de qualquer forma. Nesse caso, sessao tradicional é mais simples é segura. JWT vale a pena quando a validação stateless é genuinamente necessaria.

Comparacao com alternativas

Comparar JWT com sessoes tradicionais não é sobre qual é melhor -- é sobre qual resolve o seu problema com menos complexidade é mais seguranca.

  • Sessao + Cookie HttpOnly: revogacao imediata, mais seguro contra XSS, requer estado no servidor (Redis), ideal para apps web tradicionais
  • JWT: stateless, portavel entre serviços, sem estado no servidor, sem revogacao fácil, ideal para microservicos é tokens de curta duracao
  • Paseto: como JWT mas com API mais segura por padrão, sem vulnerabilidades de alg, mais recente é menos adotado
  • Token Opaco + Introspeccao: padrão OAuth 2.0, revogacao imediata, requer servidor de autorização, ideal para APIs públicas

Para 90% das aplicações web, sessao com cookie seria mais simples é mais segura que JWT. O problema é que os tutoriais de API REST sempre mostram JWT, então a maioria dos devs nem conhece a alternativa.

Pontos positivos é limitacoes do JWT

Pontos positivos reais: portabilidade entre dominios é serviços, sem estado no servidor de recursos (escala horizontal mais fácil), funciona bem para autenticação entre microservicos, bibliotecas disponíveis em todas as linguagens, padrão aberto é amplamente documentado.

Limitacoes que você vai encontrar: logout real requer blacklist (estado), refresh token adiciona complexidade, payload exposto (não criptografado), tamanho maior que session ID, histórico de vulnerabilidades em implementações, facilidade de cometer erros de seguranca sem perceber.

!
Pro tip: tempo de expiracao curto

Se for usar JWT, use tempos de expiracao curtos (15 a 60 minutos) com refresh token de longa duracao. O access token comprometido expira logo. O refresh token fica em cookie HttpOnly, não no localStorage.

Casos de uso reais

Dev de startup com app web é mobile: usa JWT com access token de 15min é refresh token de 30 dias em cookie HttpOnly. Mobile usa o refresh token para renovar. Funciona bem -- o custo da complexidade do refresh compensa a portabilidade entre plataformas.

Time de microservicos: serviço de autenticação emite JWT de 5 minutos. Os outros serviços validam localmente sem consultar o auth service. Sem estado compartilhado, sem Redis em todos os serviços. Expiracao curta minimiza o risco de tokens comprometidos.

Aplicação web monolitica (Django, Rails, Laravel): sessao com cookie é a escolha obvia. Todos esses frameworks tem gerenciamento de sessao embutido, seguro é testado. Não ha motivo para adicionar JWT nesse cenário.

API pública com terceiros: tokens opacos com OAuth 2.0 é servidor de autorização. Empresas que consomem a API gerenciam seus próprios tokens. Revogacao imediata quando necessario. Padrão da industria para APIs abertas.

Dicas é boas práticas

Se você decidir usar JWT, algumas práticas sao inegociaveis. Nunca armazene JWT no localStorage -- é vulnerável a XSS. Use cookie HttpOnly para o refresh token é memoria (variavel JS) para o access token. Assim o access token some quando o usuario fecha o browser é o refresh fica protegido de scripts maliciosos.

Sempre valide todos os claims: algoritmo (force no servidor, ignore o header), expiracao (exp), emissor (iss) é audience (aud). Uma biblioteca que deixa você configurar o algoritmo pelo header já é um sinal de alerta.

!
Use jti para logout seletivo

Adicione um campo jti (JWT ID) único em cada token. Ao fazer logout, guarde esse ID em uma blacklist no Redis com TTL igual ao tempo de expiracao do token. Assim você tem revogacao sem guardar todos os tokens ativos.

Vale a pena usar JWT?

Depende do contexto. JWT é uma ferramenta, não um padrão universal. A pergunta certa não é devo usar JWT? mas qual mecanismo de autenticação resolve meu problema com menos complexidade é mais seguranca?

Use JWT se: você tem multiplos serviços que precisam validar autenticação sem consultar um servidor central, precisa de tokens portaveis entre dominios, ou quer tokens de curta duracao para operações específicas como redefinicao de senha é confirmacao de email.

Evite JWT se: você está construindo uma aplicação web tradicional com frontend é backend no mesmo dominio, precisa de logout imediato é revogacao confiável, ou quer simplicidade de implementação é manutenção. Sessao com cookie HttpOnly provavelmente é a escolha mais simples é segura para você.