O que Provedores OAuth faz?
Regras
- Use o fluxo de código de autorização com PKCE para clientes públicos (SPAs, dispositivos móveis) — nunca o fluxo Implícito
- Troca de código no lado do servidor para aplicações web — o segredo do cliente nunca sai do servidor
- Parâmetro
state: gere um state aleatório, armazene-o na sessão/cookie, verifique no callback — previne CSRF
- Google OAuth: escopos
openid email profile, use id_token para obter informações do usuário
- GitHub OAuth: escopo
read:user user:email, troque o código em https://github.com/login/oauth/access_token
- Discord OAuth: escopo
identify email, endpoint de token em https://discord.com/api/oauth2/token
- Renovação de tokens: armazene
refresh_token no servidor, renove antes que o access_token expire
- Gerenciamento de sessão: crie uma sessão de aplicação no callback OAuth bem-sucedido, não armazene tokens OAuth em cookies
- Vincular contas: permita que os usuários conectem vários provedores a uma única conta por meio da tabela
accounts
Padrões
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const code = searchParams.get("code");
const state = searchParams.get("state");
if (state !== cookies().get("oauth_state")?.value) {
return new Response("State inválido", { status: 400 });
}
const tokens = await exchangeCodeForTokens(code);
const userInfo = await fetchUserInfo(tokens.access_token);
const user = await upsertUser(userInfo);
await createSession(user.id);
return redirect("/dashboard");
}
Evite
- Armazenar segredos do cliente no código frontend — sempre troque tokens no lado do servidor
- Pular o parâmetro
state — ataques CSRF são reais
- Armazenar tokens OAuth brutos em cookies — use sessões no servidor
- Esquecer de tratar o caso de "usuário já existe com esse e-mail" ao vincular provedores