OAuth é autorização, OIDC é autenticação
O OAuth 2.0 responde a apenas uma pergunta: esta aplicação pode agir em nome deste usuário? Ele fornece access tokens para APIs. Deliberadamente, ele não diz nada sobre quem é o usuário. Essa lacuna causou anos de confusão, e o OpenID Connect é a solução.
O OpenID Connect é uma pequena camada de identidade sobre o OAuth 2.0. Ele padroniza o fluxo de login, define um ID token que atesta a identidade e publica metadados para que os clientes possam ser configurados sem adivinhações. Quando você clica em “Fazer login com o Google” ou em um botão de SSO corporativo, você está usando OIDC.
A regra prática: se você precisa saber quem é o usuário, use OIDC. Se você precisa que um app faça algo em nome dele, use OAuth. A maioria dos logins precisa de ambos, e é por isso que os dois geralmente são implementados juntos.
O ID token
A peça central do OIDC é o ID token: um JWT assinado pelo provedor de identidade. Ele carrega as claims que sua aplicação precisa para estabelecer um login.
sub— o identificador estável e único do usuário.iss— o emissor, para que você saiba qual provedor o assinou.aud— o client id para o qual ele foi emitido; um token para outro app deve ser rejeitado.expeiat— quando ele expira e quando foi emitido.nonce— reflete o valor que você enviou, para vincular o token a esta tentativa de login.email,name,picture— claims de perfil, quando os scopes solicitados as permitem.
O ID token é para o seu client. Ele não é a credencial que você envia para APIs downstream — esse é o trabalho do access token. Manter os dois distintos evita um erro comum de design.
Discovery
Todo provedor compatível publica um documento de discovery:
https://accounts.example.com/.well-known/openid-configuration
Ele lista os endpoints de autorização, token, userinfo e JWKS, além dos scopes e algoritmos suportados. Os clientes buscam esse documento na inicialização e se autoconfiguram, garantindo que nada seja hard-coded e que as mudanças no provedor sejam detectadas automaticamente.
O fluxo de código de autorização com PKCE
O fluxo recomendado mantém as credenciais fora do navegador. O navegador lida apenas com um código de curta duração.
- O cliente gera um
code_verifieraleatório, cria o hash para transformá-lo em umcode_challengee redireciona o navegador para o provedor comscope=openid. - O usuário se autentica no provedor — o único lugar onde uma senha ou segundo fator é inserido.
- O provedor redireciona de volta com um
codede autorização. - O backend troca o código, junto com o verifier, por um ID token e um access token.
- O cliente valida o ID token e cria uma sessão.
O PKCE (Proof Key for Code Exchange) vincula o código ao cliente que o solicitou. Um código interceptado durante o trânsito é inútil sem o verifier. Sempre envie state para prevenir CSRF e nonce para vincular o ID token à requisição.
Escopos e claims
Os escopos decidem quais claims você pode receber.
openid— obrigatório; sem ele, a requisição é um OAuth simples, não OIDC.profile— nome, foto e outros campos de perfil.email— o e-mail do usuário e se ele está verificado.offline_access— solicita um refresh token para que o app possa agir posteriormente.
Peça apenas o mínimo necessário. Cada escopo extra representa mais dados para proteger e, para alguns provedores, gera mais fricção no consentimento do usuário.
O endpoint userinfo
O ID token geralmente carrega apenas as informações básicas. Para obter mais dados do perfil, chame o endpoint userinfo utilizando o access token:
const userinfo = await client.userinfo(tokenSet.access_token);
// { sub, name, email, email_verified, picture, ... }
Trate o sub do userinfo como a fonte oficial e certifique-se de que ele corresponde ao sub no ID token. Nunca confie em um e-mail como um identificador estável — as pessoas os alteram.
Validando o ID token
A validação é a etapa que torna todo o processo seguro, e também a etapa que mais frequentemente é feita de forma errada. Decodificar o payload não é o mesmo que verificar; qualquer pessoa pode criar um token com quaisquer claims.
Antes de confiar em uma claim:
- Assinatura (Signature) — verifique-a com a chave pública do provedor a partir do endpoint JWKS, utilizando um algoritmo permitido.
- Emissor (Issuer) —
issdeve ser igual ao provedor esperado. - Audiência (Audience) —
auddeve ser o seu client id. - Expiração (Expiry) —
expdeve estar no futuro, considerando uma pequena margem de erro no relógio (clock skew). - Nonce — deve corresponder ao valor que você enviou para este login.
Use uma biblioteca mantida, como openid-client, e deixe que ela realize essas cinco etapas. Não tente implementar o parsing de JWT manualmente para autenticação.
Sessões após o login
O OIDC autentica apenas uma vez, no momento do login. Ele não gerencia a sessão da sua aplicação. Após validar o ID token, crie sua própria sessão — um cookie ou um token — baseada no sub.
Mantenha estes três conceitos distintos:
- O ID token é para o seu cliente e comprova a identidade.
- O access token serve para realizar chamadas a APIs.
- A sua sessão é a forma como sua aplicação lembra do usuário entre as requisições.
Misturá-los pode levar ao vazamento de tokens do provedor para o navegador ou ao uso de um ID token como credencial de API, sendo ambos erros graves.
Logout
O logout local vem primeiro: limpe a sua sessão para que o usuário seja desconectado do seu app. Isso está sempre sob seu controle e é sempre confiável.
O logout federado funciona no modelo “best-effort”. Você pode redirecionar para o endpoint de encerramento de sessão do provedor com um id_token_hint, mas nem todo provedor o respeita e o redirecionamento pode não ser concluído. Projete seu sistema de forma que a limpeza da sua própria sessão seja suficiente, e nunca dependa do provedor para desconectar o usuário.
Quando usar OIDC
O OIDC é a escolha certa quando:
- Você deseja evitar completamente o armazenamento de senhas.
- Você precisa de SSO corporativo ou botões de “Entrar com…”.
- Você possui um de vários apps que devem compartilhar o mesmo login.
- Você quer que o MFA e a recuperação de conta sejam gerenciados por um especialista.
Ele é mais robusto do que um formulário de senha simples. Para uma ferramenta interna pequena com poucos usuários, Session Auth e Password Hashing podem ser mais simples e inteiramente suficientes.
Melhores práticas
- Use sempre o fluxo de código de autorização (authorization code flow) com PKCE.
- Envie e verifique tanto o
statequanto ononce. - Valide completamente o ID token — assinatura, emissor (issuer), audiência (audience) e expiração.
- Utilize discovery em vez de endpoints fixos no código.
- Solicite apenas os scopes mínimos necessários.
- Mantenha a sua sessão separada dos tokens do provedor.
- Armazene os client secrets no backend, nunca no navegador.
Erros comuns
- Tratar OAuth como autenticação e ler a identidade a partir de um access token.
- Decodificar o ID token sem verificar sua assinatura.
- Pular as verificações de
audouiss, fazendo com que um token de outro app seja aceito. - Usar o implicit flow e expor tokens na URL.
- Confiar no endereço de e-mail como a chave primária do usuário.
- Enviar tokens do provedor para suas próprias APIs como se fossem credenciais de sessão.
- Esquecer que o logout deve limpar a sua sessão primeiro.
Próximos passos
Se você ainda não leu, comece por OAuth 2.0 para entender o protocolo de autorização que o OIDC estende, e o guia de JWT para conhecer o formato do token. Assim que o login for bem-sucedido, o guia de Session Auth mostra como manter o usuário conectado, e RBAC & Permissions aborda o que eles têm permissão para fazer.