Supabase Auth na prática: verificação de e-mail, OAuth e gerenciamento de sessões

Abri o Supabase Dashboard e entrei na seção Authentication. Foi aí que travei: verificação de e-mail, Magic Link, OAuth, configuração para SSR… Eram opções demais. Qual delas usar? E como configurar?
Se você também ficou com essa dúvida, não precisa se preocupar. Quando adicionei login a um projeto pequeno, passei boa parte do dia ajustando tudo até perceber que cada método de autenticação atende a um cenário diferente. Este artigo conecta as três partes centrais do Supabase Auth: verificação de e-mail, integração OAuth e o gerenciamento de sessões que costuma causar tanta dor de cabeça. Com isso, você deve conseguir montar um sistema completo de autenticação de usuários em cerca de meia hora.
Verificação de e-mail — a forma mais básica de autenticação
Para ser sincero, a verificação de e-mail é a parte mais simples do Supabase Auth, mas também uma das mais fáceis de ignorar.
Abra o Dashboard e acesse Authentication → Providers → Email. Ali você verá uma opção chamada “Confirm Email”. Ela define se, após o cadastro, o usuário precisa verificar o endereço de e-mail antes de entrar. Em projetos hospedados, a opção vem ativada por padrão: o usuário recebe uma mensagem depois de se cadastrar e precisa clicar no link para ativar a conta.
Na primeira vez em que configurei isso, desativei a opção sem querer. O resultado? Qualquer pessoa podia informar um e-mail e entrar, e logo apareceram várias contas de spam. Só depois descobri que essa opção precisa permanecer ativada em produção.
O código de configuração é simples:
// Aciona a verificação de e-mail durante o cadastro
const { data, error } = await supabase.auth.signUp({
email: '[email protected]',
password: 'secure-password',
options: {
emailRedirectTo: 'https://yourapp.com/auth/callback'
}
})
Há um detalhe importante aqui: o parâmetro emailRedirectTo. Depois que o usuário clica no link de verificação recebido por e-mail, ele é redirecionado para esse endereço. Você pode apontá-lo para a página inicial da aplicação ou para uma página de boas-vindas específica.
Quanto aos modelos de e-mail, o Supabase inclui opções para confirmação de endereço, redefinição de senha e Magic Link. Você pode editá-las diretamente em Email Templates no Dashboard. Caso queira usar seu próprio serviço SMTP, como Resend ou SendGrid, é possível configurá-lo em Auth Hooks. Isso já é um recurso mais avançado; para começar, os modelos padrão são suficientes.
Também há uma armadilha que encontrei: a verificação de e-mail pode ficar presa no ambiente de desenvolvimento local. Isso acontece porque, por padrão, o serviço de e-mail da instância local do Supabase não envia mensagens reais. Você pode usar uma ferramenta como o Mailcatcher para visualizar os e-mails de teste ou desativar temporariamente Confirm Email durante o desenvolvimento local e reativá-lo antes de publicar a aplicação.
Integração OAuth — login com um clique
O login por OAuth faz muita diferença na experiência do usuário. Em vez de memorizar outra senha, basta clicar no botão do GitHub ou do Google para entrar, e a taxa de conversão costuma ser bem maior do que no cadastro por e-mail.
O Supabase oferece suporte a muitos provedores OAuth: GitHub, Google, Facebook, Apple, Azure, Twitter, Discord e outros, somando mais de 15 opções. Uso principalmente GitHub e Google, pois ambos têm fluxos de configuração mais claros.
Vamos começar pelo OAuth do GitHub. Primeiro, você precisa criar um OAuth App no GitHub em Settings → Developer settings → OAuth Apps → New OAuth App. O ponto essencial é preencher corretamente a Callback URL:
https://<ref-do-seu-projeto>.supabase.co/auth/v1/callback
No desenvolvimento local, use:
http://localhost:54321/auth/v1/callback
Em seguida, copie o Client ID e o Client Secret do OAuth App do GitHub para o Supabase Dashboard, em Authentication → Providers → GitHub. Depois de salvar, a chamada no cliente é bem simples:
// Login com OAuth do GitHub
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'github',
options: {
redirectTo: 'https://yourapp.com/auth/callback'
}
})
O processo do OAuth do Google é parecido, mas há uma diferença: o Google usa Client IDs separados para Web, iOS e Android. Se sua aplicação atende Web e dispositivos móveis, será preciso configurar cada plataforma individualmente.
Depois do login por OAuth, o Supabase também fornece um provider token. Ele pode ser usado para chamar APIs de terceiros: com o token do GitHub, por exemplo, você pode obter a lista de repositórios do usuário; com o token do Google, pode acessar o Google Drive. Esse recurso é especialmente útil em aplicações que integram serviços externos.
O OAuth também tem uma armadilha frequente: informar a callback URL errada durante o desenvolvimento local. Na primeira configuração, usei a porta 3000, que era a porta do meu frontend, e a página retornou um erro logo após o login. Depois descobri que o callback deve apontar para a porta do Supabase, não para a porta do frontend.
Gerenciamento de sessões — JWT e fluxo PKCE
Esta talvez seja a parte mais confusa. Quando comecei, também não entendia por completo como JWT, refresh token e PKCE funcionavam em conjunto.
Uma sessão do Supabase tem dois componentes: um access token, que é um JWT de curta duração, e um refresh token de longa duração. O access token é válido por 1 hora por padrão. A recomendação oficial é não definir um período inferior a 5 minutos, por causa de possíveis diferenças de relógio. Já o refresh token só pode ser usado uma vez e serve para obter um novo access token.
Há um detalhe importante: o refresh token tem uma janela de reutilização de 10 segundos. O que isso significa? Em um ambiente SSR, se várias requisições tentarem renovar o token ao mesmo tempo, o Supabase permitirá novas renovações dentro desses 10 segundos sem encerrar a sessão por engano. Faz sentido, pois é comum o frontend e o backend operarem a sessão simultaneamente.
Agora, o PKCE. Se você usa Next.js ou outro framework SSR, precisa configurar esse fluxo. O motivo é que o fluxo implícito expõe o token diretamente na URL, o que não é seguro em um ambiente SSR. O PKCE protege o processo de troca de tokens por meio de um code verifier.
Para configurar o PKCE, adicione dois parâmetros ao inicializar o cliente:
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
auth: {
detectSessionInUrl: true,
flowType: 'pkce'
}
})
Depois, crie uma callback route para processar a troca do code:
// Next.js App Router - app/auth/callback/route.ts
import { NextResponse } from 'next/server'
import { createClient } from '@/utils/supabase/server'
export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url)
const code = searchParams.get('code')
if (code) {
const supabase = await createClient()
const { error } = await supabase.auth.exchangeCodeForSession(code)
if (!error) {
return NextResponse.redirect(`${origin}/dashboard`)
}
}
return NextResponse.redirect(`${origin}/auth/error`)
}
Esse auth code é válido por apenas 5 minutos e só pode ser trocado uma vez. Se a troca falhar durante a depuração, é bem provável que o código tenha expirado ou já tenha sido usado.
O Supabase também oferece três modos de limitação de sessão: duração fixa (Time-boxed), que força a expiração após um período determinado; tempo limite por inatividade (Inactivity timeout), que encerra a sessão após um longo período sem atividade; e sessão única por usuário (Single session per user), em que uma conta só pode manter uma sessão ativa. Esses modos são especialmente úteis em aplicações que precisam estar em conformidade com SOC 2 ou HIPAA.
Recomendações práticas e dúvidas frequentes
Depois de tudo isso, você talvez ainda queira saber qual método de autenticação escolher.
Em resumo: a verificação de e-mail é indicada para processos de cadastro que precisam coletar dados do usuário; OAuth funciona bem quando a prioridade é entrar rapidamente, como em ferramentas para desenvolvedores ou aplicações B2B; e Magic Link atende cenários sem senha, como acessos temporários ou aplicações voltadas primeiro para dispositivos móveis.
Veja a comparação entre as três opções:
| Método | Cenário indicado | Vantagens | Desvantagens |
|---|---|---|---|
| Verificação de e-mail | Cadastro formal | Dados completos e maior controle | O usuário precisa lembrar a senha |
| OAuth | Login rápido | Sem senha e maior conversão | Depende da estabilidade de serviços externos |
| Magic Link | Acesso sem senha | Seguro e simples | É preciso consultar o e-mail a cada login |
Se você usa Next.js ou outro framework SSR, confira esta lista de configuração:
detectSessionInUrl: true— permite que o Supabase extraia automaticamente a sessão da URLflowType: 'pkce'— força o uso do fluxo PKCEredirectToconfigurado corretamente — a callback route precisa processar o auth code sem erros- Verificação das variáveis de ambiente — confirme que NEXT_PUBLIC_SUPABASE_URL e NEXT_PUBLIC_SUPABASE_ANON_KEY estão configuradas
Por fim, algumas dúvidas frequentes:
P: Por que o OAuth sempre falha no desenvolvimento local?
Na maioria das vezes, a callback URL está errada. Confira a configuração de callback do provedor no Supabase Dashboard e garanta que ela use o endereço localhost, não o domínio de produção.
P: O usuário é desconectado quando o JWT expira?
Certifique-se de que o cliente tenha um mecanismo de renovação automática. O listener onAuthStateChange do Supabase processa a renovação do token automaticamente, sem exigir uma lógica manual.
P: O que fazer quando a sessão desaparece de repente?
Esse problema é comum em ambientes SSR. Confira se o server client e o browser client foram inicializados corretamente, principalmente se os cookies estão sendo encaminhados como esperado.
Conclusão
Os três métodos de autenticação do Supabase Auth têm finalidades diferentes. A verificação de e-mail é a base e funciona bem em cadastros formais; o OAuth melhora a experiência do usuário e atende cenários que exigem login rápido; o gerenciamento de sessões oferece o suporte necessário para configurar JWT e PKCE corretamente em ambientes SSR.
As armadilhas que encontrei eram simples: callback URL incorreta, opção Confirm Email esquecida e fluxo PKCE não configurado. Depois de entender esses detalhes, fica muito mais fácil manter o sistema de autenticação estável.
Como próximo passo, depois de configurar o Auth, use Row Level Security (RLS) para proteger seus dados. O RLS do Supabase está diretamente ligado ao Auth e permite que cada usuário acesse somente os próprios dados, fechando o ciclo de segurança do sistema de autenticação.
Configurar o fluxo completo do Supabase Auth
Da verificação de e-mail e integração OAuth à configuração de PKCE em ambientes SSR
⏱️ Estimated time: 30 min
- 1
Step 1: Ativar a verificação de e-mail
No Supabase Dashboard:
• Acesse Authentication → Providers → Email
• Ative a opção Confirm Email
• Configure emailRedirectTo para apontar ao endereço de callback da aplicação
• No desenvolvimento local, use o Mailcatcher para testar os e-mails - 2
Step 2: Configurar o OAuth do GitHub
Crie a conexão OAuth entre GitHub e Supabase:
• Crie um OAuth App no GitHub em Settings → Developer settings → OAuth Apps
• Use esta Callback URL: https://<ref>.supabase.co/auth/v1/callback
• No desenvolvimento local, use: http://localhost:54321/auth/v1/callback
• Copie o Client ID e o Client Secret para o Supabase Dashboard - 3
Step 3: Configurar o fluxo PKCE
Configure um fluxo de autenticação seguro para ambientes SSR, como Next.js:
• Defina flowType: 'pkce' ao inicializar o cliente
• Ative detectSessionInUrl: true
• Crie a rota /auth/callback para processar a troca do code
• O auth code é válido por 5 minutos e só pode ser usado uma vez - 4
Step 4: Processar a renovação da sessão
Mantenha a sessão válida:
• O access token expira por padrão em 1 hora
• O refresh token só pode ser usado uma vez, com uma janela de reutilização de 10 segundos
• No cliente, escute onAuthStateChange para renovar automaticamente
• Em ambientes SSR, garanta o encaminhamento correto dos cookies
FAQ
Quais provedores OAuth são compatíveis com o Supabase Auth?
Qual é o tempo de expiração padrão do access token JWT?
Por que ambientes SSR precisam usar o fluxo PKCE?
O que fazer quando o callback do OAuth sempre falha no desenvolvimento local?
O que é a janela de reutilização do refresh token?
Como escolher entre os três métodos de autenticação?
9 min de leitura · Publicado em: 8 abr 2026 · Atualizado em: 4 set 2026
Supabase na prática
Se você chegou pela busca, o caminho mais rápido é ir para o post anterior ou próximo desta série.
Anterior
Design de banco de dados no Supabase: tabelas, relacionamentos e RLS
Veja como estruturar bancos de dados no Supabase, definir relacionamentos, criar políticas de Row Level Security e otimizar consultas com índices e funções.
Parte 2 de 7
Próximo
Supabase Storage na prática: upload de arquivos, controle de acesso e CDN
Configure o Supabase Storage com upload padrão e TUS, políticas RLS, isolamento por usuário, URLs assinadas, Smart CDN e transformação de imagens.
Parte 4 de 7



Comentários
Entre com GitHub para comentar