Voltar ao blog

Login e autenticação com Supabase, sem dor de cabeça

Guia completo de autenticação com Supabase: as funções reais do SDK, RLS com policies, redirect URLs, login com Google e os erros que travam todo mundo.

C
Caio Braga
16 de julho de 2026 · 7 min de leitura
Sumário do artigo
Login e autenticação com Supabase, sem dor de cabeça

Todo SaaS precisa de login, e construir isso do zero (senha criptografada, confirmação de e-mail, recuperação, sessão, permissões) consome semanas que seu produto não tem. O Supabase entrega tudo pronto no módulo Auth, mas a documentação espalha os detalhes, e alguns erros clássicos (o e-mail de confirmação que aponta pra localhost, a tabela que qualquer um lê porque o RLS ficou desligado) pegam quase todo mundo na primeira vez.

Este guia junta o caminho inteiro, com os nomes reais das funções e os erros pra evitar.

O que você vai precisar

Um projeto no Supabase com o SDK instalado na aplicação (npm install @supabase/supabase-js) e o cliente criado com a URL do projeto e a chave anon (as duas ficam em Settings, API, no painel). A chave anon pode ir pro frontend, é feita pra isso: quem protege os dados não é ela, é o RLS do passo 5.

Telas de cadastro, login e "esqueci a senha" na sua aplicação, mesmo que ainda sem lógica.

Pra login com Google: uma credencial OAuth no Google Cloud Console (o painel do Supabase mostra exatamente qual URL de callback colar lá).

Como o Auth do Supabase funciona

O Supabase mantém os usuários numa tabela interna gerenciada (auth.users), separada das suas tabelas. Você nunca escreve nela diretamente: as funções do SDK fazem isso. Quando alguém loga, o Supabase devolve uma sessão com um token JWT, e o SDK guarda e renova essa sessão sozinho. Em cada consulta ao banco, esse token vai junto automaticamente, e é ele que o RLS usa pra saber quem está pedindo o quê.

Isso significa que, depois de configurado, você não escreve lógica de "verificar se está logado" em cada consulta: o próprio banco nega o que o usuário não pode ver.

Passo 1: configure os métodos e as URLs (antes de escrever código)

No painel, em Authentication e Providers, deixe habilitado o Email (já vem por padrão) e habilite o Google se for oferecer.

Agora o passo que quase todo mundo pula e depois sofre: em Authentication, URL Configuration, configure o Site URL com o endereço real da sua aplicação (em produção, o domínio final; em desenvolvimento, http://localhost:5173 ou a porta que você usa) e adicione as Redirect URLs permitidas. É daqui que sai o erro mais comum do Supabase Auth: o usuário clica no link de confirmação do e-mail e cai num endereço quebrado ou no localhost, porque o Site URL ficou com o valor padrão.

Decida também, em Providers e Email, se o cadastro exige confirmação de e-mail ("Confirm email"). Com ela ligada, o usuário não consegue logar antes de clicar no link. Pra um SaaS em validação, muita gente desliga no começo (menos atrito pra testar) e liga quando o produto abre de verdade.

Passo 2: o cadastro

Na tela de cadastro, chame supabase.auth.signUp({ email, password }). Se a confirmação de e-mail estiver ligada, o retorno traz o usuário mas sem sessão ativa, e o Supabase dispara o e-mail de confirmação sozinho. Mostre uma mensagem tipo "confira seu e-mail" em vez de redirecionar pro app.

Dois detalhes que valem saber: a senha tem um tamanho mínimo configurável no painel (o padrão é 6, vale subir), e se você precisar guardar dados extras do usuário no momento do cadastro (nome, empresa), o signUp aceita um campo options.data que vai pro user_metadata, sem precisar de uma tabela extra nesse primeiro momento.

Passo 3: o login e a sessão

Na tela de login, supabase.auth.signInWithPassword({ email, password }). Sucesso devolve a sessão; erro devolve uma mensagem genérica de credencial inválida (o Supabase não diz se foi o e-mail ou a senha, de propósito, pra não confirmar a um curioso quais e-mails existem na base).

Pra sua aplicação reagir a login e logout em qualquer tela, use o supabase.auth.onAuthStateChange((event, session) => ...): é ele que te avisa quando a sessão nasce, renova ou morre, e é o jeito certo de decidir se mostra a área logada. Pra pegar o usuário atual num momento pontual, supabase.auth.getUser(). E o logout é supabase.auth.signOut().

Você não gerencia token na mão: o SDK renova a sessão sozinho enquanto o usuário estiver ativo.

Passo 4: a recuperação de senha

O fluxo tem duas pontas. Na tela de "esqueci a senha", chame supabase.auth.resetPasswordForEmail(email, { redirectTo: "https://seuapp.com/nova-senha" }). O usuário recebe um link que o loga temporariamente e o manda pra URL que você indicou (ela precisa estar na lista de Redirect URLs do passo 1, ou o link quebra).

Na página de nova senha, o usuário já chega com uma sessão válida vinda do link, então basta chamar supabase.auth.updateUser({ password: novaSenha }) com o valor do formulário. Teste esse fluxo antes de lançar: é a tela que ninguém lembra de testar e a que mais gera reclamação quando falha.

Passo 5: RLS, a parte que protege de verdade

Login funcionando não impede um usuário de ler os dados do outro. Sem RLS, qualquer pessoa com a chave anon (que está no seu frontend, visível) pode consultar qualquer tabela inteira. Esse é o erro de segurança número um em projetos Supabase.

Pra cada tabela sua que guarda dado de usuário, faça duas coisas. Primeiro, tenha uma coluna user_id (do tipo uuid) referenciando o dono da linha, preenchida no insert com o id do usuário logado. Segundo, ative o RLS na tabela (no painel, em cada tabela, ou via SQL com alter table ... enable row level security) e crie as policies. A policy clássica de "cada um só vê o que é seu" fica assim:

create policy "Usuário lê seus próprios dados"
on public.projetos
for select
using (auth.uid() = user_id);

create policy "Usuário insere seus próprios dados"
on public.projetos
for insert
with check (auth.uid() = user_id);

O auth.uid() é uma função do Supabase que devolve o id do usuário do token da requisição. Repare na diferença: using filtra o que pode ser lido ou alterado, with check valida o que pode ser gravado. Pra update, use os dois. E lembre que RLS ligado sem nenhuma policy bloqueia tudo, inclusive pro dono: se de repente "sumiram os dados" depois de ativar o RLS, está faltando a policy de select.

Teste a proteção de verdade: crie dois usuários, insira dados com um, logue com o outro e confirme que a consulta volta vazia.

Passo 6: login com Google (opcional)

No Google Cloud Console, crie uma credencial OAuth Client ID do tipo aplicação web, e em URIs de redirecionamento autorizados cole a URL de callback que o painel do Supabase mostra (algo como https://SEU-PROJETO.supabase.co/auth/v1/callback). Copie o Client ID e o Secret pro painel do Supabase, em Providers, Google.

Na aplicação, o botão "Entrar com Google" chama supabase.auth.signInWithOAuth({ provider: "google", options: { redirectTo: "https://seuapp.com/app" } }). O Supabase cuida do vai e vem com o Google e devolve o usuário logado na URL que você indicou (de novo: ela precisa estar nas Redirect URLs).

Um comportamento que vale conhecer: se a mesma pessoa se cadastrar por e-mail e depois entrar com o Google usando o mesmo endereço, o Supabase vincula as duas identidades ao mesmo usuário por padrão, então ninguém "duplica" conta.

Cuidados que evitam dor de cabeça

Configure Site URL e Redirect URLs antes de testar qualquer fluxo de e-mail. É a causa número um de link quebrado.

Nunca deixe tabela de dados de usuário sem RLS. A chave anon é pública por design, quem protege é a policy.

O e-mail de confirmação e recuperação sai, por padrão, de um servidor compartilhado do Supabase com limite baixo de envio por hora, que serve pra desenvolvimento mas não pra produção. Antes de lançar, configure um SMTP próprio (em Settings, Auth, SMTP) com um serviço como Resend ou o e-mail da sua hospedagem. Se você usa a Hostinger, o e-mail profissional do seu domínio resolve esse SMTP.

Teste o fluxo de recuperação de senha antes de lançar, sempre.

Conclusão

Autenticação com Supabase se resume a: configurar URLs e métodos no painel, ligar as quatro funções do SDK (signUp, signInWithPassword, resetPasswordForEmail, signOut) nas telas certas, escutar a sessão com onAuthStateChange, e proteger cada tabela com RLS e policies de auth.uid(). O login social entra depois com uma função só.

Quem constrói no Lovable já encontra esse padrão integrado, o Supabase Auth é o caminho nativo da plataforma, mas os detalhes deste guia (URLs de redirect, RLS, SMTP próprio) continuam sendo sua responsabilidade conferir antes de abrir o produto pro mundo. É a diferença entre um SaaS seguro e um que só parece seguro até alguém testar.

Tags
#SaaS#Supabase#autenticação#login#RLS#micro SaaS
● Não perca essa chance

Não perca a próxima edição.

Toda quinta, 9h. Direto na sua caixa.

  • Ferramentas que economizam horas do seu trabalho
  • Agentes e automações que funcionam
  • Bastidores do que estamos construindo

100% gratuito. Cancele quando quiser.

Compartilhar