Rotas protegidas no React com Supabase Auth: guia prático

Rotas protegidas no React com Supabase Auth: guia prático
Para criar rotas protegidas no React com Supabase Auth, você guarda a sessão do usuário em um contexto, escuta as mudanças de autenticação com onAuthStateChange e usa um componente que redireciona para o login quando não há sessão. Isso controla a navegação, mas a segurança real dos dados vem das políticas de Row Level Security (RLS) no banco, não do front-end.
Como funcionam as rotas protegidas no React
Em uma aplicação React com Vite, todo o código roda no navegador. Isso significa que qualquer pessoa pode abrir o DevTools e tentar acessar uma tela restrita. Por isso, uma rota protegida cumpre um papel de experiência do usuário: ela evita mostrar telas que ele não deveria ver e o leva ao login.
O fluxo básico tem três partes:
- Um provedor de autenticação que carrega e mantém a sessão.
- Um componente guardião que decide se renderiza a página ou redireciona.
- Políticas no banco que garantem que cada usuário só acesse os próprios dados.
Passo 1: criar o contexto de sessão com Supabase Auth
O cliente do Supabase oferece supabase.auth.getSession() para ler a sessão atual e supabase.auth.onAuthStateChange() para reagir a login, logout e renovação de token. Combine os dois em um contexto:
import { createContext, useContext, useEffect, useState } from 'react'
import { supabase } from './supabaseClient'
const AuthContext = createContext(null)
export function AuthProvider({ children }) {
const [session, setSession] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
supabase.auth.getSession().then(({ data }) => {
setSession(data.session)
setLoading(false)
})
const { data: listener } = supabase.auth.onAuthStateChange((_event, newSession) => {
setSession(newSession)
})
return () => listener.subscription.unsubscribe()
}, [])
return (
<AuthContext.Provider value={{ session, loading }}>
{children}
</AuthContext.Provider>
)
}
export const useAuth = () => useContext(AuthContext)
O estado loading é essencial. Sem ele, o usuário logado é redirecionado ao login por alguns milissegundos enquanto a sessão ainda está sendo recuperada.
Passo 2: criar o componente de rota protegida com React Router
Com o contexto pronto, o guardião fica simples. Ele espera o carregamento, verifica a sessão e usa Navigate para redirecionar:
import { Navigate, Outlet, useLocation } from 'react-router-dom'
import { useAuth } from './AuthContext'
export function ProtectedRoute() {
const { session, loading } = useAuth()
const location = useLocation()
if (loading) return <p>Carregando...</p>
if (!session) return <Navigate to="/login" state={{ from: location }} replace />
return <Outlet />
}
Guardar a rota de origem em state permite devolver o usuário à página que ele tentou acessar depois do login. Na configuração de rotas, basta agrupar as páginas restritas:
<Route element={<ProtectedRoute />}>
<Route path="/painel" element={<Painel />} />
<Route path="/perfil" element={<Perfil />} />
</Route>
Passo 3: a segurança de verdade está no RLS
Proteger a rota no React não protege os dados. A chave pública (anon) do Supabase fica exposta no navegador por design, e a documentação do Supabase deixa claro que a segurança deve ser aplicada com Row Level Security nas tabelas. Sem RLS, qualquer pessoa com a chave pode consultar a API diretamente.
Uma política simples para uma tabela de tarefas por usuário:
alter table public.tarefas enable row level security;
create policy "usuario ve suas tarefas"
on public.tarefas for select
using (auth.uid() = user_id);
Boas práticas para sua autenticação:
- Ative o RLS em toda tabela exposta pela API.
- Nunca coloque a chave
service_roleno front-end. - Trate o redirecionamento do React apenas como conveniência de navegação.
- Para papéis de administrador, valide a permissão no banco, não apenas no cliente.
Erros comuns ao proteger rotas
O erro mais frequente é ignorar o estado de carregamento, causando um "pisca" de redirecionamento. Outro é guardar o papel do usuário em localStorage e confiar nele para liberar telas. Um terceiro é esquecer de cancelar a inscrição do onAuthStateChange ao desmontar o componente, o que gera vazamento de listeners.
Perguntas Frequentes
O que são rotas protegidas no React? São rotas que só renderizam o conteúdo se o usuário estiver autenticado. Caso contrário, o app redireciona para a página de login.
Rota protegida no React é suficiente para garantir segurança? Não. Ela só controla a navegação. A proteção dos dados precisa ser feita no servidor, no caso do Supabase, com políticas de Row Level Security.
Como saber se o usuário está logado no Supabase?
Use supabase.auth.getSession() para ler a sessão atual e onAuthStateChange para acompanhar login e logout em tempo real.
Posso usar o mesmo padrão com Vite e Netlify?
Sim. O padrão roda no cliente, então funciona em qualquer projeto React com Vite. Em SPAs no Netlify, lembre de configurar o redirecionamento para o index.html para que as rotas funcionem ao recarregar.
Conclusão
Rotas protegidas no React com Supabase Auth se resumem a um contexto de sessão, um componente guardião e, principalmente, RLS bem configurado no banco. Comece pelas políticas e depois cuide da navegação. Na Stormcore, desenvolvemos sites, sistemas e automações com esse stack, sempre com a segurança dos dados como prioridade.
Matérias relacionadas

Reels para Empresas: Como Fazer Vídeos que Geram Clientes

IA para Pesquisa de Mercado: Como Usar na Sua Empresa

Redirecionamento 301 no Netlify: guia para React e Vite

Como Usar o Google Search Console: Guia para Empresas

IA para Análise de Dados: Guia para Pequenas Empresas

Gestão de Crise nas Redes Sociais: Guia Prático
Pronto para tirar sua ideia do papel?
Fale agora com nosso time de desenvolvimento. Sites, apps, automações, o que você precisar.
Chamar no WhatsAppResposta em até 2 horas