Next.js middleware e sessão do Supabase: 6 erros que deslogam o usuário depois do deploy
Next.js middleware e sessão do Supabase: 6 erros que deslogam o usuário depois do deploy
No localhost o login parece perfeito. Depois do deploy na Vercel, o usuário entra, recarrega a página e volta para a tela de login — ou o Server Component ainda acha que ninguém está autenticado. Quase sempre o problema não é o formulário de login: é o middleware, os cookies ou a forma como o cliente SSR lê a sessão. Estes são os seis erros mais comuns com Next.js (App Router) + Supabase.
1. Middleware que não refresca a sessão
O token de acesso expira. Sem um refresh no middleware, a cookie de sessão fica velha e o próximo request do servidor parece "deslogado", mesmo com o usuário ainda "logado" no client.
Use @supabase/ssr, crie o cliente no middleware com getAll/setAll de cookies, e chame supabase.auth.getUser() (não só getSession()) para forçar a renovação quando precisar. Se o middleware só redireciona sem tocar nos cookies, a sessão morre em silêncio.
2. getSession() no servidor como fonte da verdade
getSession() lê o JWT da cookie sem validar de novo no Auth server. Em Server Components e Route Handlers, prefira getUser(), que confirma o usuário. Usar getSession() no servidor abre a porta para cookies adulteradas e para decisões de autorização baseadas em dados não verificados.
3. Cookie options diferentes entre middleware, Server Component e Route Handler
Se um lugar grava Path=/ e outro usa um path mais estreito, ou se SameSite/Secure mudam entre ambientes, o browser manda a cookie em um request e omite no seguinte. Centralize a criação do cliente SSR (um helper só) e reutilize as mesmas opções de cookie em middleware, Server Components e Server Actions.
4. Redirect no middleware sem copiar os cookies atualizados
Quando o middleware refresca a sessão e em seguida faz NextResponse.redirect(), precisa devolver a mesma response onde os setAll gravaram as cookies. Criar um NextResponse.redirect() novo e "esquecido" das cookies atualizadas manda o usuário adiante sem a sessão renovada — sintoma clássico: login ok, primeiro redirect, página já deslogada.
5. Domínio e HTTPS: cookie Secure em HTTP local vs produção
Em produção a cookie precisa de Secure (HTTPS). Em alguns setups locais isso é afrouxado. O erro aparece quando o código de cookie é copiado sem olhar o ambiente: produção sem Secure em site HTTPS, ou preview da Vercel com Site URL do Supabase ainda apontando para localhost. Confira Authentication → URL Configuration no Supabase e as Redirect URLs de preview (https://*-seu-time.vercel.app/**).
6. Proteger a rota no client e esquecer o servidor
Um useEffect que manda para /login se não houver user melhora a UX, mas não é segurança. Server Components, Route Handlers e o middleware precisam decidir com a sessão validada. Caso contrário, HTML autenticado vaza no primeiro paint, ou APIs ficam abertas enquanto a UI "parece" protegida.
Checklist rápido
- Middleware com
@supabase/ssrrefresca viagetUser()e propaga cookies na response (incluindo redirects). - Servidor usa
getUser(), não sógetSession(). - Um único helper de cliente SSR / mesmas cookie options em todo lugar.
- Redirects do middleware reutilizam a response que recebeu os
setde cookie. - Site URL + Redirect URLs cobrem produção e preview; cookies
Secureem HTTPS. - Autorização de verdade no servidor (middleware / RSC / Route Handlers), não só no client.
Se você está montando um app Next.js com auth e banco e quer chegar mais rápido na base funcionando, uma opção é descrever o produto em linguagem natural e gerar o projeto full-stack. No Massvai a saída é Next.js + Supabase + Vercel, com código exportável ou sync com GitHub — e a checklist acima continua valendo antes de cada deploy.
Transparência: faço parte do time do Massvai, um construtor de apps com IA para full-stack Next.js, Supabase e Vercel. Estes erros são os que mais aparecem depois do primeiro deploy com login.
Fonte: https://massvai.com