OAuth 2.0 explicado sem complicação
Descubra OAuth 2.0 explicado sem complicação, quais problemas resolve e como tomar decisões melhores ao usar esse protocolo no dia a dia.
Toda vez que um dev junior implementa "login com Google" pela primeira vez, acontece a mesma confusão: ele recebe um access token, decodifica, vê um monte de informação e conclui que aquilo é a identidade do usuário. Funciona nos testes, vai pra produção, e meses depois alguém descobre que dá pra forjar a sessão porque o sistema estava confiando no token errado pra autenticar. O problema não é o código — é o modelo mental. OAuth 2.0 quase sempre é ensinado de trás pra frente.
Este post desfaz a confusão central do OAuth e mostra as decisões que de fato importam quando você o usa. Vale dizer de cara: OAuth e autenticação de sessão resolvem problemas diferentes, e se a sua dúvida é "uso token ou sessão pra login", leia JWT vs sessão, porque metade dos erros de OAuth na real são erros de autenticação disfarçados.
OAuth não é autenticação. É autorização delegada.
Essa é a frase que resolve 80% da confusão. OAuth 2.0 não foi feito pra responder "quem é esse usuário". Foi feito pra responder "esse aplicativo tem permissão de acessar esse recurso em nome do usuário". A diferença é gigante.
Pensa num cenário concreto: um app de edição de fotos quer acessar suas fotos no Google Drive. Você não quer dar sua senha do Google pro app — isso seria insano. OAuth resolve exatamente isso: você se autentica no Google, o Google pergunta "esse app pode ver suas fotos?", você aprova, e o app recebe um token que dá acesso só às fotos, sem nunca tocar na sua senha. Isso é delegação de autorização. Em nenhum momento o app de fotos "sabe quem você é" no sentido de autenticação — ele só ganhou permissão pra fazer uma coisa específica.
Quando alguém usa OAuth pra fazer login e trata o access token como identidade, está usando a ferramenta pra um problema que ela não foi projetada pra resolver. Existe uma camada em cima do OAuth pra isso — voltamos a ela no fim.
Os quatro papéis que você precisa entender
OAuth define quatro atores, e entender quem é quem desfaz a maior parte do mistério dos diagramas de fluxo:
- Resource owner: você, o usuário dono dos dados.
- Client: o aplicativo que quer acessar os dados (o app de fotos).
- Authorization server: quem autentica o resource owner e emite os tokens (o servidor de login do Google).
- Resource server: a API que guarda os dados protegidos (a API do Google Drive).
O fluxo todo é uma dança entre esses quatro: o client manda o usuário pro authorization server, o usuário aprova, o authorization server emite um token, e o client usa esse token pra falar com o resource server. Confundir authorization server com resource server é a fonte de metade dos bugs de configuração.
Authorization code flow com PKCE: o único que importa hoje
Existem vários "grant types" no OAuth, mas pra aplicações modernas a resposta é uma só: authorization code flow com PKCE (Proof Key for Code Exchange). O fluxo funciona assim:
1. Client gera um code_verifier aleatório e seu hash (code_challenge)
2. Client redireciona o usuário pro authorization server, mandando o code_challenge
3. Usuário se autentica e aprova os scopes
4. Authorization server redireciona de volta com um authorization code curto
5. Client troca o code + code_verifier por um access token
6. Authorization server confere o verifier contra o challenge e emite o token
O PKCE existe pra resolver um problema específico: e se alguém interceptar o authorization code no redirect? Sem PKCE, esse code interceptado pode ser trocado por um token. Com PKCE, o code só vale junto com o code_verifier original, que nunca trafegou pela rede no redirect. É barato de implementar e fecha um buraco real. Use sempre, inclusive em apps server-side.
Por que o implicit flow morreu
Se você achar um tutorial antigo recomendando o implicit flow, fecha a aba. O implicit flow entregava o access token direto no redirect, dentro do fragmento da URL, sem o passo de troca. Foi pensado pra uma época em que SPAs não conseguiam guardar segredo nenhum e CORS era limitado.
O problema é que jogar o token direto na URL o expõe a vazamento por histórico de navegador, logs de servidor e referrer headers. Hoje, com PKCE, uma SPA consegue fazer o authorization code flow completo sem precisar de client secret, eliminando a única razão de existir do implicit flow. A própria OAuth Security BCP recomenda não usar mais. Se a sua lib ainda oferece, é legado.
Access token, refresh token e o erro de tratar OAuth como login
O access token é de vida curta — minutos a poucas horas — e é o que você manda na requisição pra API. O refresh token é de vida longa e serve só pra uma coisa: obter um novo access token quando o atual expira, sem incomodar o usuário com novo login. Trate-os com sensibilidades diferentes: access token você manda a cada request; refresh token você guarda como ouro e nunca expõe no client se puder evitar.
Quando precisar inspecionar o que tem dentro de um token pra debugar scopes ou expiração, um decodificador de JWT mostra as claims na hora — útil pra conferir se o aud, o exp e os scope são o que você espera. Mas cuidado com a armadilha: decodificar um access token e ler claims dele pra autenticar usuário é justamente o erro que abre o post. O access token é pra autorização de acesso a recurso, não pra provar identidade.
A solução pra login é o OpenID Connect (OIDC), uma camada de identidade construída em cima do OAuth 2.0. O OIDC adiciona o id_token, um JWT cujo propósito explícito é carregar a identidade do usuário de forma verificável. Se você quer "login com Google", o que você quer é OIDC, não OAuth puro. OAuth te dá permissão; OIDC te diz quem é.
Perguntas frequentes
OAuth 2.0 serve pra fazer login?
Não diretamente. OAuth é autorização delegada — dá a um app permissão de acessar recursos em nome do usuário. Pra login, use OpenID Connect, que é uma camada de identidade construída sobre o OAuth e fornece o id_token feito pra provar quem o usuário é.
Qual a diferença entre access token e refresh token?
O access token é de vida curta e acompanha cada requisição à API. O refresh token é de vida longa e serve só pra obter novos access tokens quando o atual expira, sem novo login. Proteja o refresh token com muito mais cuidado.
Preciso de PKCE mesmo num app server-side?
Sim. PKCE deixou de ser exclusividade de SPAs e hoje é recomendado pra todos os clients, inclusive server-side. Ele fecha o risco de interceptação do authorization code com custo de implementação baixíssimo. Não há motivo pra pular.
Por que não usar mais o implicit flow?
Porque ele expõe o access token diretamente na URL do redirect, vulnerável a vazamento por histórico, logs e referrer. Com PKCE, o authorization code flow funciona em SPAs sem client secret, tornando o implicit flow obsoleto e inseguro.
O que levar daqui
A confusão do OAuth 2.0 quase sempre nasce de uma frase que ninguém disse na hora certa: OAuth é autorização delegada, não autenticação. Entenda os quatro papéis, use authorization code flow com PKCE e nada mais, trate access e refresh tokens com sensibilidades diferentes, e quando o objetivo for login, suba pro OIDC em vez de torturar um access token pra extrair identidade. O protocolo é simples quando você para de pedir que ele resolva o problema errado.
- 01 Como importar CSV sem corromper caracteres: encoding, BOM e delimitadores UTF-8, latin1, cp1252, BOM — por que seus acentos aparecem como lixo e como corrigir de uma vez, no Excel, Python e linha de comando.
- 02 IP público, privado, fixo e dinâmico: qual a diferença? RFC 1918, NAT e DHCP explicados de forma direta: o que separa IP público de privado e por que confundir fixo com dinâmico derruba servidores em produção.