1

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.

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.

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

  1. Middleware com @supabase/ssr refresca via getUser() e propaga cookies na response (incluindo redirects).
  2. Servidor usa getUser(), não só getSession().
  3. Um único helper de cliente SSR / mesmas cookie options em todo lugar.
  4. Redirects do middleware reutilizam a response que recebeu os set de cookie.
  5. Site URL + Redirect URLs cobrem produção e preview; cookies Secure em HTTPS.
  6. 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.

Carregando publicação patrocinada...