Pular para o conteúdo

Diagrama de fluxo do OpenID Connect: Authorization Code Flow, ID tokens e Discovery

Como o OpenID Connect adiciona login ao OAuth 2.0: o authorization code flow com PKCE, o ID token e sua validação, discovery, JWKS, UserInfo e logout.

· Fundador e desenvolvedor

Publicado em

Diagrama de sequência com um usuário, um navegador, uma relying party e um OpenID provider. Treze mensagens numeradas cobrem o redirecionamento, o login, a troca do código e a resposta de tokens; um fragmento critical valida o ID token e um fragmento opt chama o UserInfo.

Um app mobile faz o login de um usuário com um provedor de identidade e passa o access token para o seu backend, que chama o endpoint de perfil do provedor, obtém um endereço de e-mail e cria uma sessão. Todos os testes passam. Isso também permite que qualquer outro app em que o usuário entrou com esse provedor faça login no seu app como ele, com o próprio access token, porque nada verifica para qual app o token foi emitido.

O OpenID Connect (OIDC) fecha essa brecha. Ele adiciona um ID token ao OAuth 2.0: um JWT assinado em que o provedor informa quem é o usuário, para qual app o token se destina e quando o usuário fez login.

Este artigo desenha o authorization code flow com PKCE como diagrama de sequência e cobre o que o OIDC acrescenta: o scope openid, nonce, a validação do ID token, discovery, a rotação de chaves, UserInfo e logout.

OAuth 2.0 versus OpenID Connect

O OAuth 2.0 trata de acesso: um token para chamar uma API em nome do usuário. O OpenID Connect trata de identidade: quem fez login.

OAuth 2.0 OpenID Connect
Pergunta que responde Este app pode chamar esta API? Quem é o usuário e quando ele fez login?
Token Access token ID token
O token se destina a A API Seu app
Formato do token Não definido: opaco ou JWT Um JWT assinado
Como pedir Scopes que a API define scope inclui openid
Define Grants e endpoints Claims, UserInfo, discovery, logout

Na rede, um login OIDC é uma requisição de autorização OAuth com openid no scope, e a resposta de tokens traz um id_token ao lado do access token. O diagrama do fluxo OAuth 2.0 cobre a parte OAuth em detalhe.

O fluxo, passo a passo

O OpenID Connect Core 1.0 chama o seu app de relying party (RP) e o servidor de autorização de OpenID provider (OP). O que passa pelo navegador, o canal de frente, pode vazar para URLs, histórico e logs; as chamadas do seu backend ao provedor, o canal de fundo, não. Os números correspondem ao diagrama.

  1. Início (1–3). O usuário clica em Sign in. Seu app guarda na sessão um state, um nonce e um code_verifier de PKCE novos e redireciona o navegador para o provedor.
  2. Requisição de autenticação (4). O navegador segue o redirecionamento:
GET /authorize?response_type=code
    &client_id=orders-web
    &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
    &scope=openid%20profile%20email
    &state=7fJq2LbX9aQe
    &nonce=n-0S6_WzA2Mj
    &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
    &code_challenge_method=S256 HTTP/1.1
Host: op.example.com
  1. Login e consentimento (5). O provedor autentica o usuário (senha, passkey, MFA ou uma sessão existente) e pede consentimento. Seu app nunca vê as credenciais.
  2. Volta do código (6–7). O provedor redireciona para o redirect_uri registrado com um code de curta duração e o mesmo state, que seu app compara com o da sessão.
  3. Requisição de tokens (8–9). Seu backend envia por POST o code, o redirect_uri e o code_verifier com suas credenciais de cliente. O provedor confere o verifier com o challenge e devolve um id_token, um access_token e, muitas vezes, um refresh_token.
  4. Validação (10). Seu app valida o ID token, buscando as chaves de assinatura somente quando a que ele cita não está em cache.
  5. UserInfo (11–12), opcional. Somente quando o ID token não traz os claims de que você precisa.
  6. Sessão (13). Seu app cria a própria sessão e define um cookie.

O que state, nonce e PKCE protegem

Valor Trafega em Verificado por Impede
state A etapa 4 e o redirecionamento de volta Seu app Uma resposta de login que o usuário nunca iniciou (CSRF)
nonce A etapa 4 e depois dentro do ID token Seu app Replay do ID token e injeção de código em clientes confidenciais
code_verifier Seu hash SHA-256 na etapa 4, ele mesmo na etapa 8 O provedor Resgatar um código roubado

A melhor prática atual de segurança do OAuth, a RFC 9700, permite que um valor substitua outro em alguns casos, mas cada um custa apenas um valor aleatório, então envie os três. Clientes públicos, como aplicações de página única e mobile, devem usar PKCE (RFC 7636) com S256.

Dentro do ID token

O ID token da etapa 9, decodificado:

{
  "iss": "https://op.example.com",
  "sub": "248289761001",
  "aud": "orders-web",
  "nonce": "n-0S6_WzA2Mj",
  "iat": 1793736400,
  "exp": 1793740000,
  "auth_time": 1793736390
}
Claim Significado Seu app
iss Emissor, uma URL https Deve ser exatamente igual ao issuer descoberto
sub ID do usuário, nunca reatribuído dentro do emissor, no máximo 255 caracteres ASCII Usa iss mais sub como chave da conta
aud Audiência, uma string ou um array Deve encontrar o seu client_id nela
exp, iat Expiração e hora de emissão, em segundos Unix Rejeita tokens expirados ou muito antigos
nonce O valor enviado na etapa 4 Deve corresponder à sessão
auth_time Quando o usuário realmente se autenticou Verifica quando você envia max_age
acr, amr Nível de garantia e métodos, como pwd ou mfa Verifica antes de ações sensíveis

O Core é explícito: somente iss mais sub identifica um usuário, porque endereços de e-mail mudam e podem ser reatribuídos.

Validando o ID token

A seção 3.1.3.7 do Core lista as regras:

  1. Fixe o algoritmo (RS256 por padrão) em vez de confiar no cabeçalho alg, e nunca aceite none.
  2. Verifique a assinatura com a chave JWKS indicada por kid. O Core permite que um cliente de code flow confie no TLS em vez disso, já que o token veio direto do token endpoint, mas verificar custa pouco.
  3. Confira iss com o emissor descoberto, caractere por caractere.
  4. Confira aud para o seu client_id e rejeite audiências em que você não confia.
  5. Confira exp e iat, permitindo de segundos a alguns minutos de diferença de relógio.
  6. Confira nonce com a sessão e depois apague-o.
  7. Confira auth_time e acr se você os solicitou.

Só então crie uma sessão. Com a biblioteca jose no Node.js:

import { createRemoteJWKSet, jwtVerify } from 'jose'

// issuer and jwks_uri come from the discovery document.
// The key set is cached; an unknown kid triggers a refetch
// (at most once every 30 seconds by default).
const JWKS = createRemoteJWKSet(new URL(oidc.jwks_uri))

const { payload } = await jwtVerify(tokens.id_token, JWKS, {
  issuer: oidc.issuer,     // exact match
  audience: CLIENT_ID,     // must appear in aud
  algorithms: ['RS256'],   // never trust the header alone
  clockTolerance: 60,      // seconds of clock skew
  maxTokenAge: 600,        // rejects an old iat
})
if (payload.nonce !== session.nonce) throw new Error('nonce mismatch')

Discovery e rotação de chaves

O OpenID Connect Discovery 1.0 coloca as configurações de um provedor em um único documento JSON na URL do emissor mais /.well-known/openid-configuration. O do Google, reduzido aos campos que este fluxo usa, no momento da escrita (novembro de 2026):

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "id_token_signing_alg_values_supported": ["RS256"],
  "code_challenge_methods_supported": ["plain", "S256"]
}

O issuer deve ser idêntico à URL do emissor de onde você o buscou e ao iss de todo ID token. Configure você mesmo o emissor esperado; nunca o tire de um token que você não verificou.

As chaves rotacionam pelo jwks_uri: o provedor adiciona uma chave nova, assina com ela e mantém a antiga publicada por um tempo (Core, seção 10.1.1). Coloque o conjunto em cache, respeite Cache-Control, busque de novo diante de um kid desconhecido e limite a taxa dessas buscas. O diagrama do fluxo de autenticação JWT cobre a mesma mecânica para access tokens.

UserInfo

O UserInfo devolve claims para os scopes concedidos (profile, email, address, phone) quando você o chama com o access token. A resposta sempre contém sub, que deve corresponder exatamente ao sub do ID token, ou você descarta a resposta.

Opções de logout

Três especificações OpenID finais cobrem o logout:

Especificação Como funciona Atenção a
RP-Initiated Logout 1.0 Seu app redireciona para o end_session_endpoint do provedor com id_token_hint Seu app também deve encerrar a própria sessão
Front-Channel Logout 1.0 O provedor carrega a URL de logout de cada app em um iframe O bloqueio de cookies de terceiros pode quebrá-lo
Back-Channel Logout 1.0 O provedor envia por POST um logout token assinado a cada app Seu app deve encontrar e encerrar a sessão no servidor

O Core também observa que o exp do ID token não tem relação com a duração da sessão.

Erros que aparecem nas revisões

  • Um access token como prova de identidade. A cena de abertura. Faça login de usuários somente com um ID token que seu backend obteve do token endpoint e validou.
  • Ignorar aud ou nonce. Todo app registrado no mesmo provedor recebe ID tokens validamente assinados com o mesmo iss; só aud diz que um token foi emitido para você, e só nonce o vincula a este login.
  • O implicit flow. response_type=id_token token coloca tokens no fragmento da URL; a RFC 9700 diz que clientes não devem usar response types que devolvem access tokens na resposta de autorização. Use code com PKCE, também em aplicações de página única.
  • ID tokens enviados a APIs. As APIs devem aceitar somente access tokens emitidos para elas; o diagrama de arquitetura de um API gateway mostra onde essa verificação costuma ficar.

O diagrama do fluxo do OpenID Connect

Diagrama de sequência com um usuário, um navegador, uma relying party e um OpenID provider. Treze mensagens numeradas cobrem o redirecionamento, o login, a troca do código e a resposta de tokens; um fragmento critical valida o ID token e um fragmento opt chama o UserInfo.

16 componentes · 13 conexões

Abrir no Archboard
Conteúdo do diagrama
  • User
  • Browser
  • Relying party (your app)
  • OpenID provider
  • all checks must pass
  • claims missing from the ID token
  • ID token: for your app (aud = client_id)
  • Access token: for UserInfo and APIs
  • 1. Click Sign in
  • 2. GET /login
  • 3. 302 to the provider's /authorize
  • 4. GET /authorize: scope=openid, state, nonce, code_challenge
  • 5. Log in (password, passkey, MFA) and consent
  • 6. 302 to redirect_uri with code, state
  • 7. GET /callback?code&state
  • 8. POST /token: code, code_verifier, client auth
  • 9. id_token, access_token
  • 10. GET jwks_uri (when kid is not cached)
  • 11. GET /userinfo, Bearer access_token
  • 12. Claims; sub must match the ID token
  • 13. 302 to the app, Set-Cookie: session
O authorization code flow do OpenID Connect com PKCE. Seu app envia o navegador ao provedor com scope=openid, state, nonce e um code challenge, troca o código pelo canal de fundo e valida o ID token antes de criar uma sessão.

Como ler:

  • Quatro participantes: o usuário, o navegador, seu app (a relying party) e o OpenID provider. O tempo corre para baixo.
  • As cores mostram o canal: azul pelo navegador, verde-azulado do seu backend ao provedor, violeta para as ações do usuário. Setas tracejadas são respostas e redirecionamentos.
  • As etapas 3 e 4 carregam scope=openid, state, nonce e o challenge do PKCE; a etapa 8 carrega o verifier.
  • O fragmento critical contém a busca de chaves e as verificações que precisam passar antes de existir uma sessão. O fragmento opt é a chamada ao UserInfo.
  • A coluna da direita associa os campos de discovery às etapas, lista os parâmetros do PKCE, decodifica um ID token e mostra qual token é para quem.

Desenhando diagramas de OpenID Connect com clareza

  • Dê ao navegador a sua própria linha de vida. A divisão entre canal de frente e de fundo é a história de segurança do fluxo.
  • Escreva nas setas os parâmetros verificados: state, nonce, code_challenge, code_verifier.
  • Detalhe a validação. «Validar token» não dá para revisar; «assinatura, iss, aud, exp, iat, nonce» dá.
  • Diga qual token vai para onde, com a sua audiência. Muitos bugs de OIDC são um token enviado à parte errada.
  • Um fluxo por diagrama. Desenhe login, renovação e logout separadamente, com IDs e tokens de exemplo.

O exemplo de diagrama de sequência cobre a notação; o diagrama do fluxo SAML SSO mostra o protocolo baseado em XML que clientes corporativos ainda pedem.

Monte no Archboard

  1. Entre com Google ou GitHub e crie um diagrama.
  2. No pack Sequência, adicione um Ator para o usuário e três nós Linha de vida de mesma altura: Browser, Relying party (seu app) e OpenID provider.
  3. Desenhe as 13 mensagens como arestas retas numeradas, de cima para baixo. Deixe as respostas tracejadas e use cores diferentes para o canal de frente e o de fundo.
  4. Adicione um Fragmento combinado do pack Sequência com o operador critical em volta da busca de chaves e das verificações, e um segundo Fragmento combinado com opt em volta da chamada ao UserInfo.
  5. Adicione um Texto do pack Básico ao lado da relying party para os valores de sessão e as verificações, além de uma legenda de cores.
  6. Adicione um bloco Markdown do pack Básico para discovery, PKCE e um ID token decodificado, e dois nós Token do pack Segurança para o ID token e o access token.

O exemplo usa 9 nós de diagrama e fica dentro do plano Free. Seu agente de IA também pode desenhá-lo via MCP.

Perguntas frequentes

Qual é a diferença entre OAuth 2.0 e OpenID Connect? O OAuth 2.0 dá a um app um access token para chamar uma API. O OpenID Connect adiciona o login por cima: o scope openid, um ID token que diz quem é o usuário e endpoints padrão de discovery e UserInfo.

Um ID token é o mesmo que um access token? Não. O ID token é um JWT assinado para o seu app que diz quem fez login. O access token é para APIs, incluindo o UserInfo. Nunca envie ID tokens a APIs nem aceite access tokens como prova de login.

Preciso de PKCE se já envio um nonce? Use os dois. A RFC 9700 exige PKCE para clientes públicos. Um cliente confidencial pode contar com o nonce com precauções extras, mas o PKCE impede o resgate de um código roubado, enquanto o nonce só detecta um código injetado depois da resposta de tokens.

Como valido um ID token? Verifique a assinatura com a chave JWKS que corresponde ao seu kid e confira se iss é igual ao emissor, se aud contém o seu client ID, se exp não passou, se iat é recente e se nonce corresponde à sessão.

O que é /.well-known/openid-configuration? O documento de discovery do OpenID Connect. Ele lista o emissor, os endpoints, os algoritmos e o jwks_uri de um provedor, para que seu app possa se configurar a partir de uma única URL.

Comece grátis — um assento, sem cartão de crédito.

Artigos relacionados

← Voltar ao blog

Abra um canvas em um minuto

Entre com Google ou GitHub. Grátis para um assento. Faça upgrade quando a equipe entrar.