Fluxos OAuth no frontend
Implementar o fluxo de código de autorização com PKCE numa SPA, trocar o código por tokens, armazenar tokens de acesso com segurança e evitar o fluxo implícito.
Fluxos OAuth no frontend é uma aula grátis de Frontend Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Frontend Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Frontend Academy inclui 4 aulas no total.
O que é OAuth?
OAuth 2.0 é um protocolo de delegação: seu aplicativo obtém permissão para agir em nome do usuário em um serviço de terceiros (Google, GitHub etc.) sem jamais ver a senha do usuário. É usado no recurso 'Entrar com o Google', em aplicativos OAuth do GitHub e na maioria dos sistemas modernos de autenticação.
Funções principais
Proprietário do recurso: o usuário. Cliente: seu aplicativo. Servidor de autorização: o provedor OAuth (Google, Auth0). Servidor de recursos: a API protegida pelo token de acesso.
O fluxo do código de autorização
O fluxo padrão e seguro para aplicativos do lado do servidor: 1) Redirecione o usuário para o login do provedor. 2) O usuário entra e dá seu consentimento. 3) O provedor redireciona de volta com um código. 4) O servidor troca o código por um token de acesso (segredo exclusivo do servidor).
Por que usar PKCE em SPAs
SPAs não podem manter um segredo de cliente, pois ele estaria no pacote do navegador. O PKCE (Proof Key for Code Exchange) substitui o segredo por um verifier/challenge de código por solicitação. Agora ele é o padrão para todos os clientes OAuth públicos.
O fluxo do PKCE passo a passo
1) Gere um code_verifier aleatório. 2) Calcule o hash SHA-256 dele = code_challenge. 3) Redirecione para /authorize com o challenge. 4) Após o consentimento, receba um código de volta. 5) Troque o código + verifier por um token de acesso. O provedor verifica se challenge = hash(verifier).
Gerando o verifier e o challenge
O verifier é uma cadeia de caracteres aleatória; o challenge é a versão codificada em base64-URL do seu SHA-256.
function base64url(arr) {
return btoa(String.fromCharCode(...arr))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
async function generatePKCE() {
const arr = new Uint8Array(32);
crypto.getRandomValues(arr);
const verifier = base64url(arr);
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
const challenge = base64url(new Uint8Array(hash));
return { verifier, challenge };
}Redirecionando para o provedor
Crie a URL de autorização com o challenge, state (proteção contra CSRF) e os escopos.
const { verifier, challenge } = await generatePKCE();
const state = crypto.randomUUID();
sessionStorage.setItem('pkce_verifier', verifier);
sessionStorage.setItem('oauth_state', state);
const url = new URL('https://accounts.google.com/o/oauth2/v2/auth');
url.searchParams.set('client_id', CLIENT_ID);
url.searchParams.set('redirect_uri', `${origin}/auth/callback`);
url.searchParams.set('response_type', 'code');
url.searchParams.set('scope', 'openid email profile');
url.searchParams.set('code_challenge', challenge);
url.searchParams.set('code_challenge_method', 'S256');
url.searchParams.set('state', state);
window.location.href = url.toString();Processando o retorno
O provedor redireciona para sua URL de retorno com ?code=...&state=.... Verifique state para evitar CSRF e depois troque o código.
// /auth/callback page:
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const returnedState = params.get('state');
const expected = sessionStorage.getItem('oauth_state');
if (returnedState !== expected) throw new Error('Bad state');
const verifier = sessionStorage.getItem('pkce_verifier');
const tokens = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code,
client_id: CLIENT_ID,
redirect_uri: `${origin}/auth/callback`,
code_verifier: verifier
})
}).then(r => r.json());
// tokens: { access_token, id_token, refresh_token, expires_in }Armazenando tokens com segurança
Prática recomendada: não armazene tokens de acesso em localStorage, pois podem ser roubados por XSS. Opções: 1) Somente na memória (apagados ao atualizar — é necessária uma nova autenticação). 2) Cookie HttpOnly (definido pelo seu backend após o fluxo PKCE, não pode ser roubado por JS).
Evite o fluxo implícito
O antigo fluxo implícito retorna o token de acesso diretamente no fragmento da URL. Descontinuado pelo OAuth 2.0 Security BCP, ele vaza tokens para o histórico do navegador e os referenciadores. Use sempre Código de autorização + PKCE.
Tokens de atualização
Tokens de acesso expiram, normalmente após uma hora. Um token de atualização, com maior duração, obtém novos tokens de acesso silenciosamente. Em SPAs, tokens de atualização são cada vez mais entregues por meio de cookies HttpOnly — nunca use localStorage.
Tokens de ID vs. tokens de acesso
Token de ID (OpenID Connect): JWT que comprova quem é o usuário. Token de acesso: opaco ou JWT, usado para chamar APIs. Verifique a assinatura e as declarações do token de ID (iss, aud, exp, nonce) antes de confiar nele.
Bibliotecas de autenticação
Não implemente sua própria solução. Use: oidc-client-ts para OIDC puro, auth0/spa-js para Auth0, @clerk/clerk-react para Clerk, NextAuth.js/Auth.js para Next e Nuxt-auth para Nuxt. Elas cuidam de PKCE, atualização e armazenamento.
Verificação rápida
Por que os aplicativos de página única precisam usar PKCE (Proof Key for Code Exchange) com o fluxo do código de autorização, em vez de usar apenas o fluxo básico do código de autorização?
Recapitulação: OAuth no front-end
Código de autorização + PKCE é o padrão moderno para SPAs. Gere um verifier + challenge S256 por solicitação. Redirecione para /authorize com challenge + state. Verifique state no retorno. Troque o código + verifier por tokens. Nunca use o fluxo implícito. Prefira cookies HttpOnly para armazenar tokens. Use bibliotecas (auth0-spa-js, oidc-client-ts, NextAuth) — não implemente sua própria solução.
Perguntas Frequentes
A aula “Fluxos OAuth no frontend” é grátis?
Sim — o texto completo de “Fluxos OAuth no frontend” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Frontend Academy, atualize para CoddyKit PRO. O curso de Frontend Academy inclui 4 aulas no total.
O que vou aprender em “Fluxos OAuth no frontend”?
Implementar o fluxo de código de autorização com PKCE numa SPA, trocar o código por tokens, armazenar tokens de acesso com segurança e evitar o fluxo implícito. Você pratica Frontend Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Frontend Academy?
Nenhuma experiência prévia é necessária. Frontend Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Fluxos OAuth no frontend”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Frontend Academy?
Sim. Cada aula de Frontend Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Prevenção de XSS: codificação de saída e CSP
- CSRF: cookies SameSite e tokens
- Política de Segurança de Conteúdo: nonce e hash
- Fluxos OAuth no frontend