14 janv. 2026·8 min de lecture

Déconnexions aléatoires en production : correctifs pour cookies et sessions

Les déconnexions aléatoires en production proviennent souvent des paramètres de cookies et des proxies. Découvrez comment SameSite, Secure, le domaine et les en‑têtes peuvent supprimer silencieusement les sessions.

Déconnexions aléatoires en production : correctifs pour cookies et sessions

Pourquoi des déconnexions aléatoires surviennent après la mise en production

Une session est la façon dont votre app « se souvient » d'un utilisateur entre les chargements de page. La plupart du temps, cette mémoire se trouve dans un cookie. Soit le cookie contient un jeton signé (fréquent avec JWT), soit il contient un identifiant de session qui pointe vers des données utilisateur stockées côté serveur.

Les déconnexions “aléatoires” signifient généralement que le navigateur a arrêté d'envoyer le cookie de session à votre app. Rien ne plante. Votre serveur cesse simplement de voir une session valide, traite l'utilisateur comme inconnu et le renvoie vers la page de connexion.

C'est pour ça que tout peut sembler correct en local et se casser en production. Les tests locaux se font souvent en HTTP, sur un seul hôte et sans proxy devant l'app. La production ajoute des domaines réels, HTTPS, des CDN et des reverse proxies. Ces différences affectent la façon dont les navigateurs stockent les cookies et quand ils les joignent aux requêtes.

La perte silencieuse de session ressemble souvent à ceci :

  • Vous pouvez vous connecter, puis vous êtes déconnecté après un rafraîchissement ou quelques clics.
  • Un onglet reste connecté, un autre renvoie à la page de connexion.
  • Ça n'arrive qu'en production, ou seulement sur mobile/Safari.
  • Il n'y a pas d'erreur utile dans l'UI, juste « veuillez vous reconnecter ».

Les prototypes générés par l'IA sont particulièrement exposés parce qu'ils sont souvent livrés avec des réglages de cookie par défaut et des extraits copiés qui fonctionnaient en environnement de preview. Les déclencheurs les plus courants sont un domaine/chemin de cookie mal aligné, des valeurs SameSite qui bloquent certaines requêtes, des cookies Secure appliqués au mauvais endroit, et des problèmes d'en‑têtes proxy où l'app ne réalise pas que l'utilisateur est en HTTPS.

Si vous avez hérité d'un codebase généré par l'IA qui « marche en grande partie » mais qui déconnecte sans cesse les utilisateurs, c'est souvent l'un des premiers endroits à auditer avant de réécrire l'authentification.

Principes de base des cookies qui décident si les sessions tiennent

La plupart des problèmes de session se résument à quelques attributs de cookie. Si l'un d'eux est incorrect, le navigateur peut silencieusement arrêter d'envoyer le cookie qui identifie l'utilisateur.

Un cookie a une portée. Les éléments les plus importants sont :

  • Domain : quels noms d'hôte peuvent recevoir le cookie. Si vous le définissez pour le mauvais domaine, ou si vous oubliez que www et le domaine racine sont différents, le cookie ne sera pas envoyé sur certaines requêtes.
  • Path : quels chemins URL le reçoivent. S'il est trop restreint, les pages en dehors de ce chemin agiront comme déconnectées.
  • Expiration : combien de temps il dure. Une expiration manquante ou trop courte peut rendre une connexion instable, surtout après un rafraîchissement ou un redémarrage du navigateur.

Il existe deux durées communes. Les cookies de session disparaissent généralement à la fermeture du navigateur. Les cookies persistants ont une date d'expiration explicite, et ce sont ceux utilisés pour le “se souvenir de moi”. Si votre app attend une connexion persistante mais émet accidentellement un cookie de session, les utilisateurs penseront s'être déconnectés « sans raison ».

Le flag Secure est simple mais implacable : quand il est activé, les navigateurs n’envoient ce cookie que via HTTPS. C'est correct pour la production, mais cela casse si votre app croit être en HTTP (souvent à cause de la configuration du proxy).

SameSite contrôle quand les cookies sont envoyés à travers des « frontières de site » :

  • Lax : envoyé dans la plupart des navigations normales, mais pas dans de nombreux flux embarqués ou cross‑site.
  • Strict : envoyé uniquement sur le même site. Plus sûr, mais peut casser les redirections de connexion.
  • None : envoyé cross‑site, mais doit aussi être Secure.

Un seul attribut mal configuré peut faire « disparaître » les cookies. Le cookie peut toujours exister dans le stockage, mais il n'est pas joint aux requêtes importantes. Le serveur crée alors une nouvelle session et l'utilisateur semble déconnecté.

Paramètres SameSite qui déconnectent sans prévenir

SameSite est une règle qui dit au navigateur quand il peut envoyer votre cookie de session. S'il est trop strict, le cookie est ignoré silencieusement sur certaines requêtes et votre app semble « déconnecter » les utilisateurs au hasard.

Une configuration fréquente : votre frontend est sur app.example.com et votre API sur api.example.com. Si votre login définit le cookie de session d'une manière que le navigateur considère comme cross‑site, la requête suivante peut ne pas inclure ce cookie. L'API pense alors que l'utilisateur est nouveau et crée une session fraîche.

Les navigateurs ont resserré leurs comportements ces dernières années. Beaucoup d'anciens tutoriels présument que les cookies sont envoyés plus librement, donc une configuration qui marche sur localhost peut provoquer des déconnexions en production quand des domaines réels, HTTPS et des flux avec redirections sont impliqués.

Ce qui casse le plus souvent

Les problèmes apparaissent dans les flux qui ne sont pas de simples clics sur le même site : connexions OAuth (Google, GitHub), connexions par lien magique depuis un e‑mail, widgets embarqués dans un autre site, et certaines configurations de sous‑domaines où les redirections rebondissent entre hôtes.

Dans de nombreuses apps normales, SameSite=Lax suffit. Lax permet généralement les navigations de premier plan (comme cliquer sur un lien vers votre site) mais bloque beaucoup de requêtes en arrière‑plan ou embarquées. Si votre flux d'auth dépend des cookies pendant un callback de redirection ou dans une iframe, Lax peut échouer.

Vous aurez généralement besoin de SameSite=None quand votre cookie doit être envoyé en contexte clairement cross‑site (embeds, certains flux OAuth, et certains patterns d'API cross‑domain). Mais SameSite=None a une exigence stricte : il doit être accompagné de Secure, ce qui signifie que le cookie ne sera envoyé qu'en HTTPS.

Règles pratiques :

  • Par défaut, SameSite=Lax pour les apps mono‑site.
  • Utilisez SameSite=None; Secure pour les embeds, requêtes cross‑site ou callbacks OAuth délicats.
  • Évitez SameSite=Strict pour les sessions de connexion sauf si vous comprenez parfaitement les effets secondaires.
  • Après avoir changé SameSite, testez tout le flux de connexion sur le domaine de production réel.

Pièges HTTPS et le flag Secure

Le flag Secure indique au navigateur de n'envoyer le cookie que via HTTPS. C'est bon pour la sécurité, mais cela crée un comportement déroutant lorsqu'un trafic HTTP peut encore atteindre votre app.

Un échec classique : un utilisateur atteint la version HTTP de votre domaine, votre serveur tente de définir un cookie de session Secure, puis redirige vers HTTPS. Les navigateurs ignorent les cookies Secure définis sur une connexion HTTP. La redirection fonctionne, mais la session ne tient pas, et l'utilisateur semble déconnecté immédiatement.

Les tests locaux masquent cela parce que vous exécutez peut‑être tout en HTTP sur localhost. Ensuite vous déployez derrière HTTPS, activez Secure, et certains utilisateurs commencent à perdre leur session parce qu'une redirection au niveau d'un edge, une règle CDN ou un proxy autorise encore la requête HTTP initiale.

Staging vs production

Le staging a souvent des URLs, des réglages TLS ou des règles proxy différentes. Si le staging force HTTPS mais que la production autorise HTTP et HTTPS, le comportement des cookies sera incohérent.

Vérifiez aussi les environnements où votre app croit être en HTTP parce qu'un reverse proxy a terminé le TLS. Si l'app ne fait pas confiance aux en‑têtes forwardés, elle peut définir des cookies et des redirections basés sur le mauvais schéma.

Comment savoir que le navigateur rejette le cookie

Symptômes courants :

  • Vous voyez Set-Cookie dans la réponse, mais le cookie n'apparaît jamais dans le stockage du navigateur.
  • La connexion « fonctionne » pour une requête, puis la page suivante se charge comme déconnectée.
  • Seuls certains utilisateurs sont affectés (souvent ceux qui utilisent un ancien favori ou tapent le domaine sans HTTPS).
  • DevTools affiche des avertissements comme « This Set-Cookie was blocked » ou « Secure cookie over insecure connection. »

Si le code a été généré par l'IA et définit des cookies à plusieurs endroits, il est courant de trouver des réglages en double ou conflictuels qui rendent le phénomène aléatoire jusqu'à ce que vous retrouviez la toute première requête.

Erreurs de domaine et de chemin qui provoquent la perte de session

Obtenir un second avis
Obtenez un audit de code gratuit avant d'appliquer des correctifs.

Parfois le navigateur fait exactement ce que vous lui avez dit de faire. Il ne correspond juste pas à ce que vous vouliez.

Les cookies liés à l'hôte uniquement sont la valeur par défaut : le cookie est attaché à l'hôte exact qui l'a défini (par exemple app.example.com). Les cookies Domain sont plus larges : si vous définissez Domain=example.com, le cookie peut être envoyé à app.example.com, api.example.com et autres sous‑domaines. Aucun n'est « meilleur » par défaut, mais mélanger les deux entre services peut créer des trous de session.

Sous‑domaines : la séparation classique qui casse les sessions

Si votre frontend est sur app.example.com et votre API sur api.example.com, un cookie host‑only défini par l'API ne sera pas envoyé au frontend, et inversement. L'utilisateur semble connecté d'un côté et déconnecté de l'autre.

Faites aussi attention aux mauvaises valeurs de Domain. Domain=localhost n'est pas un réglage de production valable, et Domain=www.example.com ne couvrira pas app.example.com. Si vous utilisez un domaine personnalisé ou un CDN, l'hôte « réel » vu par le navigateur peut différer de ce que votre app suppose.

Path : un petit détail avec un grand impact

Les cookies ne sont envoyés que sur les URLs qui correspondent à leur Path. Si vous définissez Path=/api puis que l'app navigue vers /dashboard, ce cookie ne sera pas inclus. Cela arrive quand le code définit un cookie dans un groupe de routes et le lit ailleurs.

Vérifications simples :

  • Assurez‑vous que le Domain du cookie correspond à l'endroit où vous attendez son envoi.
  • Ne définissez Domain=example.com que si vous avez vraiment besoin de sessions partagées entre sous‑domaines.
  • Gardez Path=/ sauf raison forte de faire autrement.
  • Testez la connexion sur chaque sous‑domaine et sur le domaine « nu » et le www.

En‑têtes de reverse proxy qui cassent les cookies en production

Beaucoup d'apps sont derrière un reverse proxy en production (Cloudflare, Nginx, Vercel, Render, Fly.io, Railway). Le proxy termine le TLS et relaie la requête à votre app. Si votre app ne comprend pas qu'elle est derrière un proxy, elle peut croire que chaque requête arrive en HTTP, ou que l'hôte est un nom interne. Ce décalage se manifeste souvent par des « déconnexions aléatoires ».

La cause habituelle est simple : votre app construit les réglages de cookie à partir de la requête qu'elle voit. Si elle pense que la requête est en HTTP, elle peut éviter Secure ou générer une URL de redirection incorrecte. Si elle pense que l'hôte est différent, elle peut définir un cookie pour le mauvais domaine. Le navigateur ignore alors le cookie ou le garde limité à un hôte différent.

Ces en‑têtes proxy décident de ce que votre app croit :

  • X-Forwarded-Proto : schéma original (HTTP vs HTTPS)
  • X-Forwarded-Host : hôte original (votre domaine réel)
  • X-Forwarded-For : IP client originale (souvent utilisée pour le rate limiting et les règles de sécurité)

Exemple concret : un proxy envoie X-Forwarded-Proto: https, mais votre app l'ignore. Le middleware de session croit être en HTTP et définit un cookie non‑Secure. Sur un site HTTPS, les navigateurs peuvent rejeter ou mal gérer ce cookie, si bien que les utilisateurs sont déconnectés après un rafraîchissement ou une redirection.

La solution est souvent un réglage de framework (souvent appelé « trust proxy »). Attention : faire confiance aux en‑têtes proxy depuis l'internet ouvert est dangereux. Ne les faites confiance que lorsqu'un vrai proxy devant vous est la seule chose qui peut atteindre votre app.

Pas à pas : configurer correctement cookies et sessions

Si vous voyez des déconnexions aléatoires en production, ne devinez pas. Changez une variable à la fois pour identifier ce qui corrige réellement le problème.

Commencez par verrouiller l'adresse publique réelle. Notez l'URL exacte que les utilisateurs saisissent (incluant si vous utilisez www). Confirmez si le site est toujours en HTTPS dès la première requête, et si quelque chose peut atteindre un endpoint HTTP avant la redirection.

Ensuite, décidez si vous avez réellement besoin de cookies cross‑site. Vous en aurez généralement besoin lorsque l'auth se passe sur un domaine différent (courant avec OAuth), lorsque votre API est sur un sous‑domaine séparé et que vous partagez des sessions, ou lorsque vous embarquez l'app dans un autre site.

Puis alignez vos réglages de cookie sur cette réalité :

  • Pour les apps mono‑site, SameSite=Lax suffit souvent.
  • Pour les flux cross‑site, SameSite=None peut être requis, mais doit être accompagné de Secure.
  • Définissez Secure en fonction de ce que voient les utilisateurs (HTTPS), pas en fonction de ce que croit voir votre serveur.
  • Soyez intentionnel avec Domain et Path. Si vous n'avez pas besoin de partage entre sous‑domaines, ne définissez pas Domain. Gardez Path=/ dans la plupart des cas.

Enfin, traitez la cause la plus fréquente du « ça marche en local » : les proxies. Confirmez que votre proxy relaie les bons en‑têtes et que votre app est configurée pour les lire. Puis retestez comme un nouvel utilisateur : fenêtre de navigation privée, redémarrage complet du navigateur, et le flux de connexion exact incluant les redirections.

Pièges courants (surtout dans les codebases générés par l'IA)

Contrôle des paramètres de cookie
Nous vérifierons SameSite, Secure, Domain, Path et les en‑têtes proxy de bout en bout.

Les apps construites par IA fonctionnent souvent en local puis commencent à déconnecter les utilisateurs en production. L'écart vient presque toujours du comportement des cookies qui change avec de vrais domaines, HTTPS et un reverse proxy.

Un échec discret fréquent : définir SameSite=None sans Secure. Beaucoup de navigateurs ignoreront complètement ce cookie, si bien que la session ne tient jamais. Cela ressemble à une connexion réussie (vous voyez Set-Cookie), mais la requête suivante n'a pas de session.

Les erreurs de domaine sont un autre point critique. Les générateurs devinent parfois un Domain de cookie ou conservent une valeur de preview/localhost. Si le cookie est scopié sur le mauvais hôte (ou trop large), le navigateur ne l'enverra pas là où votre app l'attend.

La gestion du HTTPS en bordure (edge) fait aussi souvent trébucher les équipes. Si le trafic passe par un load balancer qui termine le TLS, votre app peut croire que les requêtes sont en HTTP à moins que vous traitiez correctement les en‑têtes forwardés. Cela conduit à des cookies et redirections qui ne correspondent pas à ce que fait le navigateur.

Enfin, les codebases IA mélangent souvent des systèmes d'auth : un cookie de session de framework plus un cookie JWT personnalisé, ou plusieurs middlewares qui mutent chacun les cookies. Cela crée un comportement « le dernier écrit gagne » qui semble aléatoire.

Une façon rapide de repérer ces problèmes est de comparer les attributs de cookie entre local et production (SameSite, Secure, Domain, Path), puis d'observer ce qui se passe pendant les redirections après la connexion.

Vérifications rapides avant de toucher quoi que ce soit

Avant de modifier des flags de cookie ou de réécrire l'auth, passez quelques minutes à confirmer ce qui se passe réellement. Beaucoup de rapports de « session expirée » sont en réalité des cas où le navigateur a cessé d'envoyer un cookie.

Si vous pouvez reproduire la déconnexion en quelques minutes, ouvrez DevTools (Application/Storage) et observez le cookie de session après l'identification. Utilisez une checklist simple :

  • Connectez‑vous et confirmez que le cookie de session apparaît.
  • Rafraîchissez deux fois et confirmez que le cookie existe toujours.
  • Déclenchez un appel API et confirmez que le cookie est envoyé avec la requête.
  • Déconnectez‑vous puis reconnectez‑vous et vérifiez que vous n'avez pas deux cookies similaires en conflit.

Confirmez ensuite si la toute première requête est toujours en HTTPS. Si la première requête arrive en HTTP puis redirige, vous pouvez finir avec des cookies reçus d'une façon que le navigateur rejette.

Si votre app et votre API sont sur des sous‑domaines différents (ou des domaines différents), notez‑le. Les règles cross‑site et la portée des cookies expliquent souvent pourquoi les connexions « tiennent parfois ».

Vérifiez aussi ce que le serveur pense être l'URL externe. Derrière un proxy, des en‑têtes forwardés incorrects peuvent faire croire à l'app qu'elle est sur le mauvais schéma ou hôte.

Enfin, comparez les navigateurs. Si cela n'arrive que sur mobile, ou seulement sur Safari vs Chrome, SameSite et les règles cross‑site sont fortement suspectes.

Scénario type : la preview marche, la production déconnecte sans cesse

Rendre l'auth stable en production
FixMyMess répare l'authentification, les cookies et les redirections pour que les connexions restent stables après le lancement.

Un modèle fréquent : une app générée par IA tourne sur app.example.com, appelle une API sur api.example.com, et les deux sont derrière un reverse proxy. La connexion semble fonctionner, mais la session ne tient pas.

En preview, tout semblait correct parce que l'app et l'API vivaient sur un hôte temporaire. Les cookies étaient simples et les redirections restaient sur la même origine.

Après la mise en production, les utilisateurs se connectent, voient brièvement le tableau de bord, puis sont renvoyés à la page de connexion après une redirection (souvent après OAuth, un lien magique par e‑mail, ou une étape « finir l'inscription »). Pas d'erreur visible, juste une perte de session silencieuse.

Ce qui se passe habituellement est une combinaison de :

  • L'API définit le cookie de session avec SameSite=None mais il manque Secure.
  • Le proxy ne transmet pas correctement X-Forwarded-Proto, ou l'app ne lui fait pas confiance.
  • Le serveur croit que la requête est en HTTP, donc il évite Secure ou génère des redirections qui rebondissent entre HTTP et HTTPS.

Les navigateurs modernes considèrent SameSite=None comme un cookie cross‑site. S'il n'est pas aussi marqué Secure, le navigateur peut l'ignorer. La réponse prétend avoir défini un cookie, mais le navigateur ne le stocke pas, et la requête suivante arrive sans session.

La correction est souvent ennuyeuse mais déterminante :

  1. Assurez‑vous que le proxy transmet les en‑têtes forwardés corrects (surtout X-Forwarded-Proto).
  2. Utilisez SameSite=None; Secure quand le comportement cross‑site est nécessaire.
  3. Confirmez la portée du cookie : ne définissez Domain que si vous avez véritablement besoin d'un partage entre sous‑domaines, et conservez Path raisonnable (généralement /).

Étapes suivantes : stabiliser votre app IA en production

Si vous voyez encore des déconnexions après avoir ajusté les flags de cookie, arrêtez les conjectures et faites une revue ciblée de l'auth/session. Une mauvaise hypothèse (faire confiance au mauvais en‑tête proxy, définir un cookie sur le mauvais hôte) peut annuler plusieurs correctifs qui semblaient logiques en preview.

Avant de modifier davantage le code, collectez un petit ensemble de faits :

  • Les attributs exacts du cookie définis (nom, Domain, Path, SameSite, Secure, HttpOnly, Max‑Age)
  • Les variables d'environnement liées à l'auth/sessions (secret de session, base URL, domaine du cookie, proxies de confiance)
  • Votre configuration reverse proxy/CDN et les en‑têtes qu'il ajoute (surtout X-Forwarded-Proto et X-Forwarded-Host)
  • Des étapes de reproduction claires (appareil/navigateur, flux de connexion, quelle page déclenche la déconnexion)
  • Quelques échantillons requête/réponse depuis la production (la réponse de login et la première requête échouée)

Si c'est un prototype généré par des outils comme Lovable, Bolt, v0, Cursor ou Replit, les problèmes de cookie/proxy apparaissent souvent avec d'autres soucis comme des patterns d'auth mélangés et des secrets exposés.

Si vous voulez une seconde paire d'yeux, FixMyMess (fixmymess.ai) se concentre sur la prise en charge des apps générées par IA pour les rendre prêtes pour la production. Un audit rapide suffit souvent à pointer le mauvais scope de cookie ou le décalage proxy exact pour que les connexions restent stables.

Questions Fréquentes

Why does my app log users out “randomly” after launch?

La plupart des déconnexions “aléatoires” se produisent lorsque le navigateur cesse d'envoyer votre cookie de session. Le serveur ne plante pas ; il reçoit simplement une requête sans session valide et considère l'utilisateur comme déconnecté.

Why does it work on localhost but fail in production?

Localhost est généralement un seul hôte, souvent en HTTP et sans reverse proxy. En production, les domaines réels, HTTPS, les redirections, les CDN et les proxies peuvent modifier la façon dont les cookies sont stockés et envoyés.

How can I quickly confirm the logout is a cookie problem?

Commencez par inspecter le cookie de session dans DevTools après la connexion et après un rafraîchissement. Vérifiez qu'il existe, qu'il a les attributs attendus (Domain, Path, SameSite, Secure, expiration) et qu'il est réellement inclus sur les requêtes qui échouent.

What SameSite setting should I use to stop logouts?

Utilisez SameSite=Lax pour une application typique mono‑site : cela stabilise généralement les connexions tout en apportant une protection. N'utilisez SameSite=None que si vous avez réellement besoin d'envoyer des cookies en contexte cross‑site, et associez‑le alors à Secure.

Why does `SameSite=None` sometimes make sessions disappear?

Les navigateurs ignorent souvent un cookie marqué SameSite=None si ce cookie n'est pas aussi marqué Secure. Le résultat : la réponse montre Set-Cookie, mais le navigateur ne le stocke pas, et la requête suivante arrive sans session.

How does the Secure flag cause immediate logout after login?

Un cookie Secure n'est stocké et envoyé qu'en HTTPS. Si la première requête arrive en HTTP (même brièvement avant une redirection), le navigateur peut rejeter le cookie, donnant l'impression d'une déconnexion immédiate après la redirection vers HTTPS.

What does “trust proxy” have to do with session stability?

Derrière un proxy, si votre app n'utilise pas ou ne fait pas confiance aux en‑têtes transférés, elle peut croire que les requêtes arrivent en HTTP ou avec un mauvais hôte. Cela conduit à des cookies créés avec un mauvais schéma ou domaine, que le navigateur n'envoie pas de façon cohérente.

Can a wrong cookie Domain or Path cause logouts on certain pages?

Oui. Un cookie limité à un hôte (host‑only) ou à un domaine trop restreint ne sera pas envoyé partout. Un Path trop spécifique empêchera l'envoi sur d'autres URLs, ce qui fera paraître l'utilisateur déconnecté sur certaines pages.

Why do I stay logged in on one subdomain but not another?

Exactement. Un cookie défini sur api.example.com ne sera pas envoyé par le navigateur à app.example.com. Si vous avez besoin d'une session partagée entre sous‑domaines, alignez intentionnellement Domain et SameSite.

What’s different about AI-built apps that makes this problem common, and how can FixMyMess help?

Les projets générés par IA mélangent souvent plusieurs approches d'auth (cookies de framework plus JWT personnalisés) et embarquent des flags de cookie par défaut qui marchaient en preview. Un audit ciblé des attributs de cookie, des en‑têtes proxy et des redirections identifie souvent rapidement la cause exacte.