JWT vs sessão com cookie: qual escolher para autenticação
As duas autenticam. A diferença está em onde mora o estado — e é isso que determina o que você ganha e o que você perde em cada uma.
Comparação direta
| JWT | Sessão com cookie | |
|---|---|---|
| Onde fica o estado | No próprio token, com o cliente | No servidor ou em um cache compartilhado |
| Revogar imediatamente | Difícil: exige lista de bloqueio | Simples: apagar a sessão |
| Escala horizontal | Não exige estado compartilhado | Exige cache compartilhado |
| Tamanho por requisição | Maior: o token viaja inteiro | Menor: só o identificador |
| Dados desatualizados | Sim, até o token expirar | Não, o servidor lê o estado atual |
| Bom para | APIs, integrações, múltiplos serviços | Aplicação web com sessão de navegador |
O problema da revogação
Um JWT é válido até expirar, e o servidor não precisa consultar nada para aceitá-lo — é justamente essa a vantagem. O preço é que revogar um token antes da hora exige guardar estado em algum lugar, o que devolve o problema que o JWT tinha eliminado.
A solução usual é reduzir a validade do token de acesso para minutos e usar um refresh token de vida longa, esse sim guardado e revogável no servidor.
Erros comuns com JWT
- Guardar o token em localStorage: fica exposto a qualquer XSS. Prefira cookie HttpOnly com SameSite
- Aceitar o algoritmo none, ou deixar o token indicar o algoritmo: fixe o esperado na verificação
- Colocar dado sensível no payload: ele é apenas Base64, qualquer um lê
- Validade longa demais: um token de 30 dias é uma credencial de 30 dias que você não consegue cancelar
- Não validar as claims exp, iss e aud
Como escolher
- Aplicação web tradicional, um back-end só: sessão com cookie resolve e é mais simples
- API consumida por aplicativo móvel ou por terceiros: JWT
- Vários serviços que precisam validar a identidade sem consultar um banco central: JWT
- Requisito de desconectar o usuário na hora: sessão, ou JWT curto com refresh token
Perguntas frequentes
- JWT é criptografado?
- Por padrão, não. Um JWT assinado (JWS) é apenas Base64 com uma assinatura: qualquer pessoa lê o conteúdo, mas não consegue alterá-lo sem invalidar a assinatura. Para conteúdo secreto existe o JWE, bem menos usado.
- Onde guardar o JWT no navegador?
- Em cookie HttpOnly com SameSite=Lax ou Strict. localStorage é acessível por JavaScript, então qualquer XSS entrega o token — e um token vazado é uma sessão inteira nas mãos de terceiros.