14 de jan. de 2026·7 min de leitura

Deslogamentos aleatórios em produção: correções de cookie e sessão

Deslogamentos aleatórios em produção geralmente são causados por configurações de cookie e proxy. Saiba como SameSite, Secure, Domain e headers fazem sessões sumirem silenciosamente.

Deslogamentos aleatórios em produção: correções de cookie e sessão

Por que deslogamentos aleatórios acontecem depois do go‑live

Uma sessão é como seu app lembra um usuário entre carregamentos de página. Na maior parte das vezes, essa memória fica em um cookie. Ou o cookie contém um token assinado (comum com JWT), ou contém um ID de sessão que aponta para dados do usuário no servidor.

Deslogamentos “aleatórios” geralmente significam que o navegador parou de enviar o cookie de sessão para seu app. Nada quebra. Seu servidor apenas para de ver uma sessão válida, trata o usuário como um estranho e o envia para a página de login.

É por isso que tudo pode parecer bem no localhost e desabar em produção. Testes locais costumam rodar em HTTP simples, um host e sem proxy na frente. Produção adiciona domínios reais, HTTPS, CDNs e proxies reversos. Essas mudanças afetam como os navegadores armazenam cookies e quando os anexam às requisições.

A perda silenciosa de sessão costuma se parecer com isto:

  • Você consegue logar, e depois é deslogado ao atualizar ou após alguns cliques.
  • Uma aba permanece logada, outra volta para o login.
  • Só acontece em produção, ou só em mobile/Safari.
  • Não há erros úteis na UI, só “faça login novamente.”

Protótipos gerados por IA são especialmente propensos a isso porque frequentemente são entregues com configurações de cookie padrão e trechos copiados que funcionavam num ambiente de preview. Os gatilhos mais comuns são domínio/path do cookie incompatíveis, valores padrão de SameSite que bloqueiam certas requisições, cookies Secure definidos no lugar errado e problemas de headers de proxy onde o app não percebe que o usuário está realmente em HTTPS.

Se você herdou uma base de código gerada por IA que “mais ou menos funciona” mas continua deslogando usuários, essa costuma ser uma das primeiras áreas a auditar antes de reescrever a autenticação.

A maioria dos problemas de sessão se resume a alguns atributos de cookie. Se qualquer um deles estiver errado, o navegador pode silenciosamente parar de enviar o cookie que identifica o usuário.

Um cookie tem um escopo. As partes que importam mais são:

  • Domain: quais hostnames podem receber o cookie. Se você definir para o domínio errado, ou esquecer que www e o domínio raiz são diferentes, o cookie não será enviado em algumas requisições.
  • Path: quais caminhos de URL o recebem. Se for muito restrito, páginas fora desse caminho agirão como deslogadas.
  • Expiração: quanto tempo dura. Uma expiração ausente ou muito curta pode fazer um login parecer instável, especialmente após um refresh ou reinício do navegador.

Existem duas durações comuns. Cookies de sessão normalmente desaparecem quando o navegador fecha. Cookies persistentes têm uma data de expiração explícita, e são o que o “lembrar de mim” normalmente usa. Se seu app espera um login persistente mas acidentalmente emite um cookie de sessão, os usuários vão jurar que foram deslogados “sem motivo”.

A flag Secure é simples, mas implacável: quando ativada, navegadores só enviam esse cookie por HTTPS. Isso é correto para produção, mas quebra se seu app pensa que está em HTTP (frequentemente por causa da configuração do proxy).

SameSite controla quando cookies são enviados através de “fronteiras de site”:

  • Lax: enviado na maioria da navegação normal, mas não em muitos fluxos embutidos ou cross‑site.
  • Strict: enviado apenas no mesmo site. Mais seguro, mas pode quebrar redirects de login.
  • None: enviado cross‑site, mas precisa também ser Secure.

Um atributo errado pode fazer cookies “desaparecerem”. O cookie pode ainda existir no armazenamento, mas não é anexado às requisições que importam. Seu servidor cria uma sessão nova e o usuário parece deslogado.

Configurações SameSite que deslogam usuários sem aviso

SameSite é uma regra do cookie que diz ao navegador quando ele pode enviar seu cookie de sessão. Se for muito restritiva, o cookie é ignorado silenciosamente em certas requisições e seu app parece “logar usuários aleatoriamente”.

Um cenário comum: seu frontend está em app.example.com e sua API em api.example.com. Se o login define o cookie de sessão de uma forma que o navegador trata como cross‑site, a requisição seguinte pode não incluir esse cookie. A API então pensa que o usuário é novo e cria uma sessão nova.

Os padrões dos navegadores apertaram nos últimos anos. Muitos tutoriais antigos assumem que cookies são enviados mais livremente, então uma configuração que funcionava no localhost vira deslogamentos em produção quando domínios reais, HTTPS e fluxos com muitos redirects entram em cena.

O que mais quebra com frequência

Os problemas aparecem em fluxos que não são um simples clique no mesmo site: logins OAuth (Google, GitHub), magic links vindos por e‑mail, widgets embutidos dentro de outro site e alguns setups de subdomínio onde redirects pulam entre hosts.

Em muitos apps normais, SameSite=Lax é suficiente. Lax normalmente permite cookies em navegações de topo (como clicar em um link para seu site), mas os bloqueia em muitas requisições de background ou embutidas. Se seu fluxo de auth depende de cookies durante um callback de redirect ou dentro de um iframe, Lax ainda pode falhar.

Geralmente você precisa de SameSite=None quando seu cookie precisa ser enviado num contexto claramente cross‑site (embeds, alguns setups OAuth e certos padrões de API cross‑domain). Mas SameSite=None tem uma exigência rígida: deve vir junto com Secure, ou seja, o cookie só será enviado por HTTPS.

Uma regra prática:

  • Use SameSite=Lax por padrão para apps padrão de um único site.
  • Use SameSite=None; Secure para embeds, requisições cross‑site ou callbacks OAuth complicados.
  • Evite SameSite=Strict para sessões de login, a menos que você entenda totalmente os efeitos colaterais.
  • Após mudar SameSite, teste todo o fluxo de login no domínio real de produção.

Armadilhas do flag Secure e HTTPS

A flag Secure diz ao navegador para enviar o cookie apenas por HTTPS. Isso é bom para segurança, mas cria comportamento confuso quando algum tráfego HTTP ainda chega ao seu app.

Um erro clássico: um usuário acessa a versão HTTP do seu domínio, seu servidor tenta definir um cookie de sessão Secure e então redireciona para HTTPS. Navegadores ignoram cookies Secure definidos via HTTP. O redirect funciona, mas a sessão não “gruda”, então o usuário parece deslogado imediatamente.

Testes locais escondem isso porque você pode rodar tudo via HTTP no localhost. Depois de fazer deploy atrás de HTTPS, ativar Secure e permitir que alguns usuários cheguem primeiro por HTTP (uma regra de CDN, redirecionamento no edge, etc.) pode causar perdas de sessão.

Diferenças entre staging e produção

Staging frequentemente tem URLs, configurações TLS ou regras de proxy diferentes. Se staging força HTTPS mas produção permite ambos HTTP e HTTPS, o comportamento de cookies será inconsistente.

Também fique atento a ambientes onde seu app pensa que está em HTTP porque um proxy reverso termina o TLS. Se o app não confia nos headers encaminhados, ele pode definir cookies e redirects baseados no esquema errado.

Sintomas comuns:

  • Você vê Set-Cookie na resposta, mas o cookie nunca aparece no armazenamento do navegador.
  • O login “funciona” por uma requisição, depois a página seguinte carrega como deslogada.
  • Só alguns usuários são afetados (frequentemente quem usa um bookmark antigo ou digita o domínio sem HTTPS).
  • DevTools mostra avisos como “This Set-Cookie was blocked” ou “Secure cookie over insecure connection.”

Se estiver lidando com uma base de código gerada por IA que define cookies em vários lugares, é comum encontrar definições duplicadas ou conflitantes de cookie que fazem o problema parecer aleatório até rastrear a primeira requisição.

Erros de Domain e Path que causam perda de sessão

Depurar com um especialista
Descreva seu passo a passo de logout e diremos o que inspecionar primeiro.

Às vezes o navegador está fazendo exatamente o que você mandou. Só que não bate com o que você quis.

Cookies host‑only são o padrão: o cookie fica ligado ao host exato que o definiu (por exemplo, app.example.com). Cookies com Domain são mais amplos: se você definir Domain=example.com, o cookie pode ser enviado para app.example.com, api.example.com e outros subdomínios. Nenhum dos dois é “melhor” por padrão, mas misturar ambos entre serviços pode criar lacunas de sessão.

Subdomínios: a divisão clássica que quebra sessões

Se seu frontend vive em app.example.com e sua API em api.example.com, um cookie host‑only definido pela API não será enviado para o host do frontend, e vice‑versa. O usuário parece logado de um lado e deslogado do outro.

Também preste atenção em valores Domain incorretos. Domain=localhost não é uma configuração real de produção, e Domain=www.example.com não cobre app.example.com. Se você usa um domínio customizado ou um CDN, o host “real” que o navegador vê pode diferir do que seu app assume.

Path: um detalhe pequeno com grande impacto

Cookies só são enviados em URLs que batem com seu Path. Se você definir Path=/api e depois seu app navegar para /dashboard, aquele cookie não será incluído. Isso aparece quando o código define um cookie em um grupo de rotas e tenta lê‑lo em outro lugar.

Algumas checagens de sanidade:

  • Garanta que o Domain do cookie bate com onde você espera que ele seja enviado.
  • Só defina Domain=example.com se realmente precisar de sessões entre subdomínios.
  • Mantenha Path=/ a menos que tenha um motivo forte para não fazê‑lo.
  • Teste o login em todos os subdomínios e tanto no domínio “naked” quanto no www.

Headers de proxy reverso que quebram cookies em produção

Muitos apps ficam atrás de um proxy reverso em produção (Cloudflare, Nginx, Vercel, Render, Fly.io, Railway). O proxy termina o HTTPS e encaminha a requisição para seu app. Se seu app não entende que está atrás de um proxy, pode achar que toda requisição é HTTP, ou que o host é um nome interno. Essa incompatibilidade muitas vezes aparece como “logouts aleatórios”.

A causa usual é simples: seu app monta as configurações de cookie a partir da requisição que vê. Se ele pensa que a requisição é HTTP, pode pular Secure ou gerar a URL de redirect errada. Se pensa que o host é outro, pode definir cookie para o domínio errado. O navegador então ignora o cookie ou mantém ele escopado longe do site real.

Esses headers de proxy decidem no que seu app acredita:

  • X-Forwarded-Proto: esquema original (HTTP vs HTTPS)
  • X-Forwarded-Host: host original (seu domínio real)
  • X-Forwarded-For: IP do cliente original (usado para rate limits e regras de segurança)

Um exemplo concreto: um proxy envia X-Forwarded-Proto: https, mas seu app ignora isso. O middleware de sessão pensa que está em HTTP e define um cookie não‑Secure. Num site HTTPS, navegadores podem rejeitar ou tratar mal esse cookie, então usuários são deslogados após um refresh ou redirect.

A correção costuma ser uma configuração do framework (comummente chamada “trust proxy”). Tenha cuidado: confiar em headers de proxy vindos da internet aberta é inseguro. Confie neles apenas quando um proxy real à sua frente for a única coisa que pode alcançar seu app.

Passo a passo: configurar cookies e sessões corretamente

Se você está vendo deslogamentos aleatórios em produção, não chute. Mude uma variável por vez para saber o que realmente consertou.

Comece travando o endereço público real. Anote a URL exata que os usuários digitam (incluindo se usam www). Confirme se o site é sempre HTTPS na primeira requisição e se algo pode atingir um endpoint HTTP antes de redirecionar.

Depois, decida se realmente precisa de cookies cross‑site. Geralmente precisa quando a autenticação acontece em um domínio diferente (comum com OAuth), quando sua API está em um subdomínio separado e vocês compartilham sessões, ou quando o app é embutido dentro de outro site.

Então alinhe as configurações de cookie com essa realidade:

  • Para apps de um único site, SameSite=Lax costuma ser suficiente.
  • Para fluxos cross‑site, SameSite=None pode ser necessário, mas deve vir junto com Secure.
  • Defina Secure com base no que os usuários veem (HTTPS), não no que seu servidor acha que vê.
  • Seja intencional com Domain e Path. Se não precisa compartilhar entre subdomínios, não defina Domain. Mantenha Path=/ na maioria dos casos.

Finalmente, trate a causa mais comum de “funciona localmente”: proxies. Confirme que seu proxy encaminha os headers corretos e que seu app está configurado para lê‑los. Depois reteste como um usuário novo: janela anônima, reinício completo do navegador e o fluxo de login exato incluindo redirects.

Armadilhas comuns (especialmente em bases geradas por IA)

Verificação de configurações de cookie
Verificamos SameSite, Secure, Domain, Path e headers de proxy de ponta a ponta.

Apps gerados por IA muitas vezes funcionam no localhost e começam a deslogar pessoas em produção. A lacuna quase sempre é o comportamento do cookie quando domínios reais, HTTPS e um proxy reverso entram na equação.

Uma falha silenciosa comum é definir SameSite=None sem Secure. Muitos navegadores irão ignorar esse cookie completamente, então a sessão nunca fica persistente. Pode parecer que o login funcionou (você viu Set-Cookie), mas a requisição seguinte chega sem sessão.

Erros de Domain são outro grande problema. Geradores às vezes chutam um Domain do cookie ou carregam um valor de preview/localhost. Se o cookie está escopado para o host errado (ou escopado mais amplamente do que o pretendido), o navegador não o enviará onde seu app espera.

O tratamento de HTTPS na borda também complica. Se o tráfego alcança um load balancer que termina TLS, seu app pode acreditar que as requisições são HTTP a menos que você trate corretamente os headers encaminhados. Isso leva a cookies e redirects incompatíveis com o que o navegador está fazendo.

Por fim, bases geradas por IA frequentemente misturam sistemas de auth sem perceber: um cookie de sessão do framework mais um cookie JWT personalizado, ou múltiplos middlewares cada um modificando cookies. Isso cria comportamento de “último escritor vence” que parece aleatório.

Uma maneira rápida de localizar esses problemas é comparar atributos de cookie entre local e produção (SameSite, Secure, Domain, Path) e então observar o que acontece durante redirects após o login.

Checagens rápidas antes de mudar qualquer coisa

Antes de mexer nas flags de cookie ou reescrever autenticação, passe alguns minutos confirmando o que está realmente acontecendo. Muitos relatórios de “sessão expirada” são na verdade “o navegador parou de enviar um cookie”.

Se você consegue reproduzir o logout em poucos minutos, abra o DevTools (Application/Storage) e observe o cookie de sessão depois de assinar. Use uma linha de base simples:

  • Faça login e confirme que o cookie de sessão aparece.
  • Atualize duas vezes e confirme que o cookie ainda existe.
  • Acione uma chamada à API e confirme que o cookie é enviado com a requisição.
  • Faça logout e login novamente e confirme que você não acaba com dois cookies semelhantes.

Depois confirme se a primeira requisição é sempre HTTPS. Se a primeira batida é HTTP e então redireciona, você pode acabar com cookies definidos de uma forma que o navegador rejeita.

Se seu app e API vivem em subdomínios diferentes (ou domínios diferentes), anote isso. Regras cross‑site e escopo de cookie frequentemente explicam porque logins “às vezes grudam”.

Também verifique o que o servidor acha que é a URL externa. Atrás de um proxy, headers encaminhados errados podem fazer o app acreditar estar no esquema ou host errado.

Finalmente, compare navegadores. Se só acontece no mobile, ou só no Safari vs Chrome, SameSite e regras de cookie cross‑site são um forte suspeito.

Exemplo: preview funciona, produção continua deslogando

Segure o código enquanto corrige
Corrigimos problemas comuns como segredos expostos e riscos de injeção junto com as correções de autenticação.

Um padrão comum: um app gerado por IA roda em app.example.com, chama uma API em api.example.com, e ambos ficam atrás de um proxy reverso. O login parece funcionar, mas a sessão não gruda.

No preview parecia tudo bem porque app e API viviam num host temporário. Cookies eram simples, e redirects ficavam na mesma origem.

Depois de entrar em produção, usuários fazem login, veem o dashboard brevemente e então são devolvidos à tela de login após um redirect (frequentemente depois de OAuth, magic link por e‑mail ou um passo de “completar cadastro”). Sem erro óbvio, apenas perda silenciosa de sessão.

O que costuma estar acontecendo é alguma combinação de:

  • A API define o cookie de sessão com SameSite=None, mas falta Secure.
  • O proxy não encaminha X-Forwarded-Proto corretamente, ou o app não confia nele.
  • O servidor acredita que a requisição é HTTP, então omite Secure ou gera redirects que pulam entre HTTP e HTTPS.

Navegadores modernos tratam cookies SameSite=None como cookies cross‑site. Se não estiverem também marcados Secure, o navegador pode descartá‑los. Assim a resposta afirma que definiu um cookie, mas o navegador nunca o armazena, e a requisição seguinte chega sem sessão.

A correção costuma ser chata, porém decisiva:

  1. Garanta que o proxy encaminha os headers de forwarded corretos (especialmente X-Forwarded-Proto).
  2. Use SameSite=None; Secure quando comportamento cross‑site for necessário.
  3. Confirme o escopo do cookie: defina Domain apenas se realmente precisar de compartilhamento entre subdomínios e mantenha Path sensato (normalmente /).

Próximos passos: estabilizar seu app gerado por IA em produção

Se você ainda vê logouts após ajustar flags de cookie, é hora de parar de chutar e fazer uma revisão focada de auth/sessão. Uma suposição errada (como confiar no header de proxy errado, ou definir cookie no host errado) pode desfazer várias “correções” que pareciam corretas num ambiente de preview.

Antes de mudar mais código, recolha um pequeno conjunto de fatos:

  • Os atributos exatos do cookie que estão sendo definidos (nome, Domain, Path, SameSite, Secure, HttpOnly, Max‑Age)
  • Variáveis de ambiente relacionadas a auth/sessões (session secret, base URL, cookie domain, trusted proxies)
  • Sua configuração de reverse proxy/CDN e quais headers ele adiciona (especialmente X-Forwarded-Proto e X-Forwarded-Host)
  • Passos claros para reproduzir (dispositivo/navegador, fluxo de login, qual página dispara o problema)
  • Alguns exemplos de requisição/resposta da produção (resposta de login e a primeira requisição que falha)

Se este for um protótipo gerado por IA de ferramentas como Lovable, Bolt, v0, Cursor ou Replit, problemas de cookie/proxy aparecem frequentemente junto com problemas maiores como padrões de auth mistos e segredos vazados.

Se quiser uma segunda opinião, FixMyMess (fixmymess.ai) foca em pegar apps gerados por IA e deixá‑los prontos para produção. Uma auditoria curta geralmente encontra o escopo de cookie ou a incompatibilidade de proxy exata para que os logins fiquem estáveis.

Perguntas Frequentes

Por que meu app desloga usuários “aleatoriamente” após o lançamento?

A maioria dos deslogamentos “aleatórios” acontece quando o navegador para de enviar o cookie de sessão. O app não quebra; ele apenas recebe uma requisição sem sessão válida e trata o usuário como deslogado.

Por que funciona no localhost e falha em produção?

Localhost costuma ser um único host, muitas vezes em HTTP, e sem proxy reverso. Produção adiciona domínios reais, HTTPS, redirects, CDNs e proxies — e essas diferenças podem mudar se o cookie é armazenado e anexado às requisições.

Como posso confirmar rapidamente que o logout é um problema de cookie?

Comece inspecionando o cookie de sessão no DevTools após o login e depois de um refresh. Confirme que ele existe, tem os atributos esperados (Domain, Path, SameSite, Secure, expiração) e que é realmente enviado nas requisições que falham.

Que configuração SameSite devo usar para evitar logouts?

Use SameSite=Lax para um app típico de um único site — geralmente mantém o login estável e oferece alguma proteção. Use SameSite=None apenas quando precisar realmente do cookie em contextos cross‑site, e então combine com Secure.

Por que `SameSite=None` às vezes faz as sessões desaparecerem?

O navegador ignora um cookie com SameSite=None se ele não estiver também marcado como Secure. Isso costuma parecer que o login teve sucesso (você vê Set-Cookie), mas o cookie nunca é armazenado, então a requisição seguinte chega sem sessão.

Como a flag Secure pode causar logout imediato após o login?

Um cookie Secure só é armazenado e enviado via HTTPS. Se o primeiro acesso for HTTP (mesmo que redirecione), o navegador pode rejeitar o cookie, fazendo o usuário parecer deslogado imediatamente após o redirecionamento para HTTPS.

O que 'trust proxy' tem a ver com estabilidade de sessão?

Se seu app está atrás de um proxy e não confia nos headers encaminhados, ele pode acreditar que as requisições são HTTP ou que o host está errado. Isso pode levar a cookies criados com esquema ou domínio equivocados, que os navegadores não enviam de forma consistente.

Um Domain ou Path errado pode causar logouts em certas páginas?

Sim. Se o Domain do cookie for muito restrito (por exemplo apenas www), algumas páginas ou serviços não o receberão. Se o Path for muito específico (por exemplo \/api``), rotas fora desse caminho não enviarão o cookie e os usuários parecerão deslogados nessas páginas.

Por que fico logado em um subdomínio, mas não em outro?

Exato. Um cookie host‑only definido em api.example.com não será enviado para app.example.com, então um lado pode ver sessão enquanto o outro não. Se precisar de sessão compartilhada entre subdomínios, alinhe intencionalmente Domain e SameSite.

O que há de diferente em apps criados por IA que torna esse problema comum, e como o FixMyMess ajuda?

Projetos gerados por IA frequentemente misturam abordagens de autenticação (cookies de sessão do framework + JWTs personalizados) e vêm com flags de cookie padrão que só funcionavam em ambiente de preview. Uma auditoria focada em atributos de cookie, headers de proxy e redirects normalmente encontra o descompasso exato.