Como os aplicativos lembram de você
Você faz login. Você clica em alguma coisa. O servidor não tem a menor ideia de quem você é.
O HTTP é stateless: cada requisição chega do zero, sem memória da anterior e sem nenhum jeito embutido de conectar as duas. O login que deu certo há um segundo não deixou rastro nenhum.
Então um aplicativo que precisa reconhecer você entre requisições precisa guardar a identidade em algum lugar e recuperá-la a cada requisição seguinte.
Toda esta seção gira em torno de uma única pergunta: onde a identidade mora?
Quase todo fluxo de login na web responde isso de uma entre três formas.
O servidor lembra
Na identidade stateful, o servidor guarda a informação.
Quando você faz login, o servidor cria uma sessão, um pequeno pacote de dados que representa você: um id de usuário, um nome, talvez um papel. Essa sessão vive no servidor. O navegador recebe um cookie carregando um id de sessão, nada mais, e o envia automaticamente em toda requisição para aquele domínio. O servidor pega o id, busca a sessão correspondente e sabe de novo quem você é.
Esse é o padrão tradicional de aplicativo web, e o comportamento padrão em muitos frameworks. Se você já usou o express-session, era isso que ele estava fazendo.
Tudo o que importa sobre você fica no servidor, e o id só é útil para quem também consegue acessar esse servidor.
O cliente carrega a prova
Na identidade stateless, o servidor não guarda nada sobre você.
O cliente mantém um token e o envia a cada requisição. O servidor verifica o token e responde, sem precisar consultar nada sobre quem você é entre uma requisição e outra.
Isso funciona bem para APIs, aplicativos mobile e sistemas distribuídos, onde memória compartilhada entre servidores é complicada ou inexistente. Se você já chamou uma API e recebeu 401 Unauthorized: missing authorization header, é esse modelo pedindo que você traga sua prova.
Existem duas versões disso, e a diferença importa o suficiente para que cada uma ganhe seu próprio capítulo. Um token opaco (bearer token) é uma string aleatória sem significado que o servidor precisa consultar. Um JSON Web Token carrega a identidade dentro de si mesmo, assinada, de modo que nenhuma consulta é necessária.
Ele ainda tem um banco de dados cheio de usuários. O que ele deixa de manter é o registro do fato de que você está logado neste exato momento.
Alguém mais garante por você
Na identidade delegada, um terceiro em quem você confia confirma quem é o usuário em seu nome.
Seu aplicativo pergunta ao Google se ele reconhece essa pessoa. O Google faz o login e entrega ao seu aplicativo um token comprovando a resposta. Todo botão "Entrar com o Google", "Entrar com o GitHub" e "Entrar com a Apple" é isso.
O atrativo é que você deixa de manter um sistema de senhas. Sem armazenamento de senha, sem fluxo de redefinição, sem vazamento de credenciais que você nunca chegou a guardar. OAuth e identidade delegada explica como essa transferência realmente funciona.
É por isso que você é redirecionado para uma página do Google e depois trazido de volta. A comprovação aconteceu lá.
Lado a lado
| Stateful | Stateless | Delegado | |
|---|---|---|---|
| Onde a identidade mora | No servidor | No token que o cliente carrega | Com o provedor |
| Custo por requisição | Uma consulta | Uma verificação de assinatura, ou uma consulta | Depende do token que você acaba usando |
| Revogar acesso | Imediato | Difícil, geralmente espera a expiração | Em parte, decisão do provedor |
| Escala horizontalmente | Precisa de um repositório compartilhado | Livremente | Livremente |
| Principal coisa que você sacrifica | Coordenação entre servidores | A capacidade de mudar de ideia | Controle e independência |
Nenhuma delas é a resposta certa. Elas otimizam para coisas diferentes, e é por isso que sistemas reais costumam usar mais de uma ao mesmo tempo: um login delegado para estabelecer quem você é, uma sessão para o site, tokens para a API.
A única frase que vale a pena levar para o próximo capítulo: stateful é para controle, stateless é para escala, delegado é para passar o problema para outra pessoa.
Experimente
Para cada sistema, indique o modelo que você esperaria e a propriedade que decide isso.
- Um painel administrativo interno onde revogar o acesso de alguém precisa surtir efeito imediatamente.
- Uma API pública atendendo um aplicativo mobile com algumas centenas de milhares de usuários.
- Um aplicativo de fotos cujo cadastro inteiro é um botão "Continuar com o Google".
- Uma arquitetura de microsserviços onde uma dezena de serviços precisa saber quem está chamando.
Compare suas respostas
| # | Modelo | A propriedade decisiva |
|---|---|---|
| 1 | Stateful | Revogação imediata. Apague a sessão e a próxima requisição fica anônima. Nada mais oferece isso. |
| 2 | Stateless | Não há repositório de sessão compartilhado para coordenar conforme o tráfego cresce, e os clientes mobile carregam um token sem problema. |
| 3 | Delegado | Nenhum sistema de senhas para construir, armazenar ou ter vazado, e o cadastro mais rápido possível. |
| 4 | Stateless, especificamente JWTs | Cada serviço consegue verificar o token sozinho, sem precisar perguntar a um servidor central a cada chamada. |
O número 1 é o mais interessante. É o menor sistema da lista e o que tem menos pressão de escala, e mesmo assim leva o modelo que escala pior, porque aqui controle importa mais do que crescimento.
Para onde isso vai a seguir
Três famílias, cada uma resolvendo um problema de um jeito diferente.
Sessões e cookies desmonta a primeira: o que o servidor armazena, o que o navegador carrega, e os erros que transformam um modelo sólido em um modelo furado.

