OAuth e identidade delegada
Todo botão "Sign in with Google" representa uma decisão de não manter um sistema de senhas.
Seu app não verifica uma senha, não confirma a identidade da pessoa e nunca armazena uma credencial. Ele pergunta a um provedor em quem já confia, e aceita a resposta.
O protocolo por trás disso é o OAuth, e o fluxo tem mais engrenagens do que o botão sugere.
Duas autorizações diferentes
Existe uma confusão que pega quase todo mundo, e vale a pena esclarecê-la antes que o fluxo faça sentido.
Você já viu a tela de consentimento: um app pedindo seu nome, foto de perfil e endereço de e-mail. Às vezes mais, às vezes muito mais, como contatos, agenda e todas as mensagens da sua caixa de entrada.
Essa tela é sobre autorização, e não tem nada a ver com os papéis (roles) do seu app. Ela decide quais partes da conta Google do usuário seu app pode acessar, e essas permissões são chamadas de scopes.
Seus próprios papéis de admin e de usuário continuam sendo decididos dentro do seu back-end, depois que o login termina, exatamente como nos capítulos anteriores.
OAuth autoriza, OIDC identifica
Rigorosamente falando, o OAuth concede autorização delegada: permissão para o seu app agir sobre um recurso. A camada de identidade construída em cima dele é o OpenID Connect, ou OIDC, e os botões "sign in with" são, na verdade, OIDC.
Essa distinção importa na prática do código. Um access token do OAuth diz o que seu app pode acessar; um ID token do OIDC diz quem é o usuário. Tratar o primeiro como prova de identidade é um erro comum e real.
O Google decide quais dos seus dados do Google o app pode ver. Seu app decide o que essa pessoa pode fazer depois que ela entra. Perguntas diferentes, lugares diferentes, respostas diferentes.
A ida e volta
Oito etapas, e o usuário sai do seu app bem no meio delas:
- O usuário clica no botão dentro do seu app.
- Seu app redireciona o usuário para o Google.
- O usuário faz login diretamente com o Google. Seu app não vê nada disso.
- O Google mostra a tela de consentimento para os scopes que você pediu.
- Se o usuário concordar, o Google envia ao seu servidor um código de aprovação de uso único. Esse código não loga ninguém. Ele representa apenas o consentimento, nada mais.
- Seu servidor envia esse código de volta ao Google, junto com as credenciais secretas do seu próprio app.
- Essas credenciais provam ao Google que a solicitação veio do seu back-end.
- O Google responde com um ID token dizendo quem é o usuário, e seu app faz o login dele.
A troca em duas etapas, das etapas cinco a oito, é a parte que vale a pena entender. O código passa pelo navegador do usuário e é inútil sozinho; o token que realmente importa é trocado diretamente entre servidores, onde nenhum navegador chega a vê-lo.
É essa a vantagem: você não consegue vazar uma credencial que nunca recebeu.
Três formas de dar errado
Mandar o usuário para longe e confiar que o provedor vai trazê-lo de volta abre três brechas silenciosas.
| O que dá errado | Por que isso importa | A correção | |
|---|---|---|---|
| 1 | Pedir demais | Scopes além do que o app usa significam que um vazamento expõe muito mais do que deveria, e os usuários perdem a confiança num app que parece intrometido. Divulgação de informação | Peça o menor conjunto de scopes que suas funcionalidades realmente usam |
| 2 | Vazamento do código de aprovação | O código aparece na barra de endereço, no histórico do navegador, em ferramentas de analytics ou em logs do servidor. Qualquer um que o veja antes de expirar pode terminar o login como aquele usuário. Falsificação (spoofing) | Mantenha-o fora de qualquer coisa que fique registrada em log, e troque-o imediatamente |
| 3 | Confiar no ID token sem verificar | Qualquer um pode escrever um token com a cara certa. Só o Google pode assinar um de verdade. Aceitá-lo sem verificação permite que um atacante finja ser qualquer pessoa. Falsificação (spoofing) | Verifique a assinatura, a audience e a expiração antes de confiar em qualquer coisa dentro dele |
A falha 3 é a que desmonta o modelo inteiro. O sentido de delegar era que uma parte confiável garantisse a identidade do usuário; pular a verificação significa passar a confiar em quem quer que tenha enviado a solicitação.
Qualquer um pode escrever um bilhete. Verificar a assinatura é como você sabe que esse veio do Google, e pular essa verificação é confiar numa letra que você nunca viu antes.
Mão na massa
Cinco situações de uma integração OAuth real. Identifique a falha, o risco e a correção.
- Seu app só precisa de um endereço de e-mail para logar as pessoas, mas a solicitação OAuth também pede contatos, agenda e arquivos do Drive.
- A tela de consentimento avisa que seu app quer permissão para excluir eventos da agenda. Seu app nunca mexe na Agenda.
- Depois do login, a página mostra brevemente o código de aprovação de curta duração na URL.
- Seu back-end recebe o ID token e o aceita sem verificar a assinatura ou para quem ele foi emitido.
- Seu back-end aceita um ID token que expirou há uma hora.
Compare suas respostas
| # | Falha | Risco | Correção |
|---|---|---|---|
| 1 | Pedir demais | Um token vazado expõe muito mais da conta do usuário do que o app jamais precisou | Peça apenas os scopes que uma funcionalidade usa |
| 2 | Pedir demais | A mesma exposição, além de uma tela de consentimento que faz o app parecer suspeito antes mesmo de alguém usá-lo | Remova o scope não utilizado |
| 3 | Vazamento do código de aprovação | URLs ficam registradas em log, salvas e compartilhadas. Quem capturar o código antes que ele expire pode completar o login | Mantenha os códigos fora da URL, troque-os imediatamente |
| 4 | Confiar no ID token | Qualquer um pode forjar algo com cara de token. Sem verificar assinatura e audience, um atacante pode se passar por qualquer usuário | Verifique a assinatura e a audience antes de confiar nele |
| 5 | Confiar no ID token | Um token antigo pode ser reaproveitado para logar repetidamente como aquele usuário | Verifique a expiração e rejeite qualquer token vencido |
As falhas dois e um são a mesma falha com consequências diferentes, por isso vale ler a lista como três problemas, não cinco. Quatro e cinco também são uma única falha: verificação é um conjunto de checagens, e pular qualquer uma delas é pular a verificação.
Para onde isso leva
Três modelos, cada um resolvendo o mesmo problema por um caminho diferente. O servidor lembra, o cliente carrega a prova, ou um provedor garante a identidade.
Escolhendo um modelo de identidade coloca os três lado a lado e explica quando cada um é a resposta certa.

