Todos os artigos
165 artigos · atualizado semanalmente Veja nossas Ferramentas
Todos os artigos
Tutoriais

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.

OAuth 2.0 explicado sem complicação
COVER · Tutoriais

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.

RD
Autor
Rafael Duarte
Desenvolvedor backend com passagem por fintech e SaaS B2B — trabalhou em times que escalaram APIs de zero a milhões de requisições. Carrega cicatrizes de produção suficientes para ter opiniões fortes sobre ferramentas, padrões e decisões de arquitetura. Não é acadêmico: leu a RFC do UUID quando precisou escolher entre v4 e v7 para uma tabela de alta escrita.
Ver perfil