
Como tokens e sessões funcionam — aprendi implementando autenticação do zero
Em 2019 implementei autenticação pela primeira vez. Guardei token em localStorage, não validava expiração, e não sabia a diferença entre sessão e JWT. Aprendi caro.
Quando implementei autenticação pela primeira vez, minha solução foi: usuário envia login + senha, backend verifica, retorna token (string aleatória gerada com uuid4()), frontend guarda em localStorage, nas próximas requests manda no header, backend consulta o banco para ver se o token existe.
Funcionou. O problema: o token nunca expirava, ficava em localStorage para sempre, e qualquer pessoa com acesso ao localStorage tinha acesso à conta.
Aprendi sobre sessões e JWT quando precisei integrar com um sistema que usava os dois. Sessão baseada em servidor:
Login → servidor cria sessão no banco/memória → retorna session_id no cookie
Request → cliente envia session_id → servidor consulta memória/banco → valida
Logout → servidor deleta a sessão
O estado fica no servidor. O cliente só tem um ID. Logout funciona imediatamente — você deleta a sessão e o ID não serve para nada.
JWT (JSON Web Token):
Login → servidor cria token assinado com informações do usuário → retorna token
Request → cliente envia token → servidor valida assinatura + expiration → sem consulta ao banco
Logout → token continua válido até expirar (a menos que você implemente blacklist)
O estado fica no token. Mais rápido, funciona melhor com múltiplas instâncias do servidor.
O tradeoff que ninguém me explicou na época:
| | Sessão | JWT | |--|--------|-----| | Revogação imediata | ✅ Deleta no servidor | ❌ Válido até expirar | | Performance | Consulta banco | Sem consulta | | Estado distribuído | Difícil (sessão precisa ser compartilhada) | Fácil (qualquer servidor valida) | | Logout | Funciona | Requer blacklist |
Para sistema pequeno com um servidor: sessão resolve melhor. Para múltiplos servidores ou microserviços: JWT faz mais sentido.
O erro de localStorage: qualquer script rodando na página consegue ler o token — incluindo scripts de terceiros e, em caso de XSS, scripts maliciosos. Cookies com HttpOnly são mais seguros: o JavaScript da página não consegue ler.
response.set_cookie(
"session_id",
value=token,
httponly=True,
secure=True, # só HTTPS
samesite="Lax"
)
Aprendi isso depois de ler sobre XSS e entender que "está funcionando" não é o mesmo que "está seguro".