O fluxo implicito expunha access token na URL e a BCP de segurança do IETF o removeu das recomendações no RFC 9700 (2025). Em cliente público, SPA ou app mobile, você implementa authorization code com PKCE e valida cada claim do ID token antes de confiar em dado de usuário. Este post percorre o fluxo e as armadilhas que a produção cobra.

Os papéis e o que cada um guarda

OAuth separa quatro papéis: o resource owner é o usuário, o client é sua aplicação, o authorization server emite tokens e o resource server protege a API. Cliente público não guarda secret, e por isso o PKCE existe. O redirect URI entra registrado no authorization server com comparação exata; URI com curinga abre redirect aberto, e aí um atacante captura o code no retorno.

Você testa o redirect com porta diferente, com subdomínio parecido e com path relativo. A RFC 9700 (IETF, 2025) lista URI mal validada entre os vetores de token interception.

O fluxo PKCE passo a passo

Você gera um code_verifier aleatório, calcula o hash SHA-256 e envia o code_challenge junto da autorização. O authorization server guarda o challenge. Na troca do code por token, você envia o verifier e o servidor compara os dois. O RFC 7636 (IETF, 2015) descreve o par. Atacante que intercepte o code no dispositivo não possui o verifier e a troca falha. O jwt-autenticacao-completa" class="post-internal-link">refresh token rotaciona: o servidor emite um refresh novo a cada uso e invalida o anterior; reuso detectado revoga a família inteira.

ID token não é access token

OIDC camada em cima do OAuth e acrescenta o ID token, JWT assinado pelo authorization server. Access token protege a API; ID token autentica o usuário no client. Antes de ler nome, e-mail ou e-mail verificado, você valida assinatura, iss, aud e nonce contra o discovery document do servidor. O OpenID Connect Core 1.0 (OpenID Foundation, 2014) define a separação entre os dois tokens.

Armadilhas de produção

SPA que guarda access token em localStorage entrega caminho livre a XSS: um script injetado lê a chave e chama a API como você. Padrão BFF (Backend for Frontend) mantém sessão em cookie httpOnly e o backend fala OAuth com o authorization server. Sessão termina com logout RP-initiated: o client pede o encerramento no servidor e redireciona o usuário de volta. Sua suíte de segurança roda cada endpoint com token expirado, token de outro client e token sem escopo; buracos de autorização aparecem nesses três testes.