Rien ne fait plus monter la tension que le patron qui écrit : « Je n’arrive pas à me connecter à WordPress. Il indique que les cookies sont bloqués. » Vous essayez vous-même. Même erreur. Vous ouvrez DevTools et… le navigateur a l’air normal. Les cookies fonctionnent partout ailleurs. Alors pourquoi WordPress se comporte-t-il comme en 2004 ?
Ce message n’est pas un diagnostic. C’est WordPress qui hausse les épaules en imperméable. Le vrai problème est presque toujours l’un de ceux-ci : des en-têtes qui n’atteignent pas le navigateur, une détection HTTPS incorrecte, un cache qui renvoie la mauvaise réponse, ou un proxy/CDN qui réécrit tout en absurdité. Nous allons le traiter comme un incident : reproduire, capturer des preuves, isoler la couche, corriger la cause et ajouter des garde-fous pour éviter un retour à 2 h du matin.
Ce que le message signifie vraiment (et ce qu’il ne signifie pas)
Quand WordPress affiche « Les cookies sont bloqués ou non pris en charge par votre navigateur », ce n’est que rarement votre navigateur. WordPress affiche ceci quand le flux de connexion ne parvient pas à confirmer un aller-retour du cookie de session.
En termes simples, WordPress attend cette séquence :
- Votre navigateur demande
/wp-login.php. - Le serveur répond avec un en-tête
Set-Cookie(cookie test ou cookie d’auth selon l’étape). - Votre navigateur renvoie ce cookie sur la requête suivante.
- WordPress voit le cookie et poursuit. S’il ne le voit pas, vous obtenez le message « les cookies sont bloqués » ou une boucle de redirection.
Si le cookie ne revient pas, WordPress ne peut pas dire si vous êtes authentifié, si vous pouvez stocker des cookies du tout, ou si la requête de connexion est un lecture depuis un cache. WordPress vous renvoie alors ce message générique.
Ce que ce n’est généralement pas
- Ce n’est pas un réglage du navigateur, sauf si vous êtes dans un environnement très verrouillé ou en mode vie privée inhabituel.
- Ce n’est pas « WordPress est en panne ». La plupart des sites servent encore des pages ; seule la connexion est cassée.
- Ce n’est pas un correctif permanent que de « vider les cookies et réessayer ». Si effacer les cookies aide, c’est un indice, pas une solution.
Ce que c’est généralement
- En-têtes modifiés ou supprimés (proxy/CDN/WAF, PHP-FPM mal configuré, règles de cache incorrectes).
- Confusion HTTP/HTTPS (WordPress pense être en HTTP, définit des cookies sans Secure, ou génère des redirections incorrectes).
- Décalage de portée du cookie (domaine/chemin non correspondant,
siteurlethomeincorrects, noms d’hôtes mixtes). - Interférence du cache (cache de page, cache proxy inverse, cache d’objets ou CDN qui met en cache
/wp-login.phpou des réponses de redirection). - Sur-intervention d’un plugin/couche de sécurité (réécriture d’en-têtes, injection de redirections, modification incorrecte des politiques SameSite).
Idée paraphrasée attribuée à Werner Vogels (CTO d’Amazon) : Tout échoue parfois ; construisez des systèmes et des habitudes qui supposent l’échec et se rétablissent rapidement.
Cela s’applique ici. Traitez la connexion comme un chemin critique. Observez-la, protégez-la et n’autorisez pas « vider les cookies » à devenir votre plan opérationnel.
Vérification de réalité sur les cookies : faits et brève histoire
Les cookies sont étonnamment petits pour la quantité de chaos qu’ils provoquent. Quelques faits concrets vous donnent de meilleures intuitions lors du dépannage.
- Fait 1 : HTTP est sans état par conception. Les cookies ont été un hack pragmatique pour conserver l’état entre les requêtes sans redessiner le web.
- Fait 2 : Les cookies viennent de l’ingénierie web de l’ère Netscape (mi‑années 1990). Ils étaient utiles bien avant d’être controversés.
- Fait 3 : Un cookie n’est qu’un en-tête. Concrètement, le serveur envoie
Set-Cookieet le client renvoieCookie. Si un proxy manipule les en-têtes, votre « problème de navigateur » est en réalité l’infrastructure. - Fait 4 : Les navigateurs modernes appliquent des règles de cookie beaucoup plus strictes qu’avant—particulièrement pour
SameSite, les requêtes cross-site et les contextes tiers. - Fait 5 : L’attribut
Securebloque les cookies sur HTTP. Utile pour la sécurité. Nuisible pour une terminaison TLS mal configurée où l’application pense être en HTTP. - Fait 6 : De nombreux bugs de connexion se manifestent comme des boucles de redirection, pas comme des erreurs explicites de cookie, parce que l’application tente sans cesse d’établir une session.
- Fait 7 : WordPress a historiquement toléré de nombreux environnements d’hébergement étranges (hébergement mutualisé, ports non standards, proxies bizarres). Cet héritage implique plusieurs façons de configurer la même chose—et autant de façons de mal la configurer.
- Fait 8 : Certains CDN et plugins « d’optimisation » mettent en cache agressivement des redirections et du HTML. S’ils mettent en cache les réponses
wp-login.php, vous servez en fait un flux de connexion précédemment généré à tout le monde. Ce n’est pas « optimisation » ; c’est de la roulette.
Blague #1 : Les cookies sont de petits fichiers qui peuvent ruiner votre week-end. Le deuxième pire cookie à trouver en production est celui que vous n’avez pas défini.
Plan de diagnostic rapide (premier/deuxième/troisième)
Si vous faites du SRE assez longtemps, vous apprenez à aimer un bon playbook. En voici un qui trouve le coupable rapidement sans fouiller les réglages des plugins comme si c’était une maison hantée.
Premier : Prouvez si Set-Cookie est envoyé et renvoyé
- Capturez les en-têtes de réponse de
/wp-login.phpet le POST vers/wp-login.php. - Confirmez que le navigateur (ou curl) renvoie le cookie sur la requête suivante.
- Si
Set-Cookiemanque ou change de façon inattendue entre les sauts, arrêtez de blâmer le navigateur.
Second : Identifiez « l’edge » qui possède les en-têtes
- Y a‑t‑il un CDN ? Un WAF ? Un reverse proxy ? Un contrôleur d’ingress ? Une couche de cache Nginx ?
- Contournez-le temporairement (IP/port d’origine direct, override hosts, réseau interne) et comparez les en-têtes.
- Si l’origine fonctionne mais que l’edge échoue, vous avez votre suspect.
Troisième : Validez les hypothèses HTTPS et hôte canonique
- WordPress doit être d’accord avec la réalité sur : le schéma (https), l’hôte (www vs apex) et le chemin.
- Vérifiez
siteurlethomedans la base de données. - Vérifiez les en-têtes proxy :
X-Forwarded-Proto,X-Forwarded-Host, et les valeurs$_SERVERvues par WordPress.
Quand escalader immédiatement
- Vous voyez des réponses mises en cache pour
/wp-login.phpou/wp-admin/. - Les en-têtes
Set-Cookiesont supprimés ou réécrits par l’edge. - Le site est derrière SSO, un proxy d’entreprise, ou des règles CSP strictes qui ont changé récemment.
Causes racines que vous pouvez réellement réparer
1) Mauvais schéma ou hôte : WordPress définit les cookies au mauvais endroit
Si WordPress pense tourner sur http:// mais les utilisateurs y accèdent via https://, les cookies peuvent être émis sans les bons attributs, les redirections peuvent rebondir, et le cookie d’auth peut ne jamais être accepté.
Scénarios fréquents :
- Le TLS est terminé sur un load balancer, mais l’origine ne reçoit pas
X-Forwarded-Proto: https. - Vous forcez HTTPS à l’edge, mais WordPress génère encore des URLs en HTTP en interne.
- Noms d’hôtes canoniques mixtes : le formulaire de connexion post vers
example.com, mais le cookie est pourwww.example.com(ou inversement).
2) Couches de cache : la connexion ne doit pas être « optimisée »
Tout cache qui stocke ou rejoue des réponses de connexion peut casser les cookies. Cela inclut :
- Règles CDN qui incluent accidentellement
/wp-login.php. fastcgi_cacheNginx appliqué trop largement.- Plugins de cache WordPress qui mettent en cache les pages d’administration ou de connexion.
- Règles edge qui mettent en cache les réponses 301/302 de façon trop agressive.
La connexion est dynamique. L’auth est par utilisateur. Si vous la mettez en cache, vous n’accélérez pas le site ; vous cassez la réalité de base.
3) Attributs SameSite et Secure : les navigateurs modernes sont plus stricts
Les règles de cookie modernes sont plus strictes sur les contextes cross-site. La plupart des connexions WordPress sont first-party, donc vous évitez généralement les problèmes SameSite. Mais dès que vous introduisez :
- des formulaires de connexion intégrés,
- des flux SSO,
- des plugins OAuth avec callbacks cross-domain,
- ou des « connexion depuis un domaine différent » ,
…vous pouvez voir des cookies refusés si les attributs ne sont pas correctement définis.
4) Décalage domaine/chemin du cookie causé par la dérive de configuration
WordPress a plusieurs mécanismes pour décider du domaine et du chemin des cookies. Si vos WP_HOME, WP_SITEURL, les valeurs en base et l’URL d’accès réel ne sont pas alignés, vous pouvez facilement définir des cookies pour le mauvais domaine ou chemin.
5) Plugins de sécurité, WAFs et « durcissements » qui cassent les en-têtes
Les produits de sécurité aiment réécrire les en-têtes. Parfois ils le font correctement. Parfois ils suppriment Set-Cookie pour des raisons de « confidentialité ». Ou ils injectent des redirections qui font perdre les cookies. Ou ils bloquent les POSTs vers /wp-login.php sous des règles trop larges.
6) Sortie PHP avant les en-têtes (oui, encore)
Si quelque chose echo ou imprime avant que WordPress ne définisse les cookies, PHP peut émettre un comportement « headers already sent », ce qui signifie que votre Set-Cookie ne quitte jamais le serveur. Cela arrive souvent avec des thèmes cassés, des modifications personnalisées de wp-config.php, ou des plugins qui impriment des espaces/encodage BOM en tête de fichier.
7) Dérive d’horloge et comportements TTL étranges
L’expiration des cookies dépend du temps. Si les serveurs ont un décalage d’horloge, les cookies peuvent apparaître immédiatement expirés, surtout dans des clusters multi‑nœuds où un nœud émet et un autre valide. C’est plus rare, mais réel.
Blague #2 : La synchronisation temporelle est le tueur silencieux—parce que rien ne dit « connexion sécurisée » comme un serveur qui vit dans le futur.
Tâches pratiques : commandes, sorties et décisions
Ci‑dessous des tâches pratiques que vous pouvez exécuter depuis un hôte ayant accès réseau au site (ou depuis le serveur web lui‑même). Chacune inclut une sortie réaliste et la décision à prendre en fonction. Exécutez-les dans l’ordre si vous voulez une traçabilité propre des preuves.
Task 1: Fetch /wp-login.php headers and confirm Set-Cookie exists
cr0x@server:~$ curl -skI https://www.example.com/wp-login.php | sed -n '1,20p'
HTTP/2 200
date: Sat, 27 Dec 2025 11:05:12 GMT
content-type: text/html; charset=UTF-8
cache-control: no-store, no-cache, must-revalidate, max-age=0
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly; SameSite=Lax
x-powered-by: PHP/8.2
server: nginx
Ce que cela signifie : WordPress émet un cookie test ; c’est bon signe. Si vous ne voyez pas set-cookie du tout, soit les en-têtes sont supprimés en amont soit PHP ne les envoie pas.
Décision : Si absent, contournez le CDN/proxy ensuite (Task 3). Si présent, vérifiez qu’il est renvoyé (Task 2).
Task 2: Confirm the cookie round-trip works with curl
cr0x@server:~$ curl -sk -c /tmp/cj.txt https://www.example.com/wp-login.php >/dev/null
cr0x@server:~$ cat /tmp/cj.txt
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
www.example.com FALSE / TRUE 0 wordpress_test_cookie WP%20Cookie%20check
cr0x@server:~$ curl -sk -b /tmp/cj.txt -I https://www.example.com/wp-login.php | grep -i set-cookie
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly; SameSite=Lax
Ce que cela signifie : curl a stocké et renvoyé le cookie avec succès. Si le serveur se plaint encore dans le navigateur, le problème peut venir du cache, des redirections ou d’un décalage hôte/schéma dans le chemin du navigateur.
Décision : Si le cycle curl fonctionne mais que les navigateurs échouent, inspectez les redirections et la canonicalisation de domaine (Tasks 4–6).
Task 3: Bypass the CDN/reverse proxy by hitting the origin (or internal LB) directly
cr0x@server:~$ curl -sI http://10.20.30.40/wp-login.php | sed -n '1,15p'
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=UTF-8
Set-Cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; HttpOnly; SameSite=Lax
Ce que cela signifie : L’origine définit le cookie, mais notez qu’il manque Secure en HTTP. Si les utilisateurs accèdent via HTTPS à l’edge, WordPress peut devoir être informé qu’il est en HTTPS pour définir les bons attributs et URLs.
Décision : Corrigez la détection HTTPS derrière le proxy (voir Tasks 10–11) et assurez-vous que l’edge transmet X-Forwarded-Proto.
Task 4: Check redirect chain for login and admin
cr0x@server:~$ curl -skIL https://example.com/wp-admin/ | sed -n '1,40p'
HTTP/2 301
location: https://www.example.com/wp-admin/
cache-control: max-age=3600
date: Sat, 27 Dec 2025 11:06:11 GMT
HTTP/2 302
location: https://www.example.com/wp-login.php?redirect_to=https%3A%2F%2Fwww.example.com%2Fwp-admin%2F&reauth=1
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly; SameSite=Lax
HTTP/2 200
content-type: text/html; charset=UTF-8
Ce que cela signifie : Les redirections sont attendues, mais notez cache-control: max-age=3600 sur une redirection canonique. Si votre CDN met en cache ce 301/302 de façon agressive pour les chemins de connexion, vous pouvez rester coincé dans une boucle ou servir des réponses périmées.
Décision : Ajoutez des règles « no cache » pour /wp-login.php, /wp-admin/ et les redirections liées à l’auth au niveau du CDN/proxy.
Task 5: Verify siteurl and home in the database
cr0x@server:~$ mysql -u wpuser -p -D wordpress -e "SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl','home');"
+-------------+------------------------+
| option_name | option_value |
+-------------+------------------------+
| home | https://example.com |
| siteurl | https://www.example.com|
+-------------+------------------------+
Ce que cela signifie : Noms d’hôtes mixtes. C’est un générateur classique de décalage de portée cookie et peut produire des boucles de connexion.
Décision : Faites-les correspondre à votre hôte canonique (généralement les deux https://www.example.com ou les deux apex). Mettez à jour prudemment (Task 6) et assurez des redirections cohérentes.
Task 6: Fix home and siteurl (carefully)
cr0x@server:~$ mysql -u wpuser -p -D wordpress -e "UPDATE wp_options SET option_value='https://www.example.com' WHERE option_name IN ('home','siteurl');"
cr0x@server:~$ mysql -u wpuser -p -D wordpress -e "SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl','home');"
+-------------+-----------------------+
| option_name | option_value |
+-------------+-----------------------+
| home | https://www.example.com |
| siteurl | https://www.example.com |
+-------------+-----------------------+
Ce que cela signifie : Hôte canonique aligné. Cela résout souvent les bizarreries de domaine/chemin de cookie et les boucles de redirection.
Décision : Retestez la connexion. Si c’est toujours cassé, passez à l’inspection des en-têtes à l’edge (Task 7) et aux vérifications de cache (Task 8).
Task 7: Compare edge vs origin Set-Cookie and cache headers
cr0x@server:~$ curl -skI https://www.example.com/wp-login.php | egrep -i 'set-cookie|cache-control|server|via|cf-cache-status|x-cache'
server: cloudflare
cf-cache-status: HIT
cache-control: public, max-age=14400
Ce que cela signifie : Un hit de CDN sur /wp-login.php. C’est un cratère fumant, pas un indice.
Décision : Contournez immédiatement la mise en cache pour les chemins de connexion/admin au niveau du CDN et purgez les objets mis en cache. Puis retestez.
Task 8: Inspect Nginx config for caching of login/admin paths
cr0x@server:~$ sudo nginx -T 2>/dev/null | sed -n '/fastcgi_cache/,+25p'
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=PHP:100m inactive=60m;
map $request_uri $skip_cache {
default 0;
~*/wp-admin/ 1;
~*/wp-login.php 1;
}
server {
location ~ \.php$ {
fastcgi_cache PHP;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
add_header X-Cache $upstream_cache_status;
}
}
Ce que cela signifie : Cette config fait la bonne chose : elle ignore le cache pour la connexion/l’admin. Si votre config manque ces exclusions, vous pouvez casser l’auth.
Décision : Si absent, ajoutez les exclusions et rechargez Nginx. Si présent, vérifiez si la map correspond réellement à vos chemins (certaines configurations utilisent des préfixes ou réécritures différentes).
Task 9: Test whether login/admin responses are being cached anyway
cr0x@server:~$ curl -skI https://www.example.com/wp-login.php | egrep -i 'x-cache|cache-control|set-cookie'
cache-control: no-store, no-cache, must-revalidate, max-age=0
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly; SameSite=Lax
x-cache: MISS
Ce que cela signifie : No-store et un MISS de cache sont sains. Si vous voyez HIT ou des en-têtes de cache public, corrigez d’abord les règles de cache.
Décision : Si le cache est propre, concentrez-vous sur le schéma/en-têtes forwardés et les attributs cookie.
Task 10: Verify the reverse proxy forwards HTTPS indication
cr0x@server:~$ sudo nginx -T 2>/dev/null | sed -n '/proxy_set_header X-Forwarded-Proto/,+10p'
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
Ce que cela signifie : Le proxy transmet le schéma qu’il voit. Si le TLS est terminé avant ce proxy, $scheme peut être http même pour un utilisateur en HTTPS, ce qui est incorrect.
Décision : Si le TLS est terminé dans un load balancer en amont, définissez X-Forwarded-Proto https là-bas, ou transmettez l’en-tête original et faites-lui confiance prudemment.
Task 11: Confirm WordPress sees HTTPS on the origin
cr0x@server:~$ php -r 'var_export([ "HTTPS"=>($_SERVER["HTTPS"]??null), "HTTP_X_FORWARDED_PROTO"=>($_SERVER["HTTP_X_FORWARDED_PROTO"]??null) ]);'
array (
'HTTPS' => NULL,
'HTTP_X_FORWARDED_PROTO' => NULL,
)
Ce que cela signifie : Dans ce contexte shell vous n’avez pas d’en-têtes de requête, mais cela illustre ce que vous recherchez en contexte réel : WordPress s’appuie sur des variables serveur. Si les requêtes ne les remplissent pas, WordPress peut mal se comporter derrière des proxies.
Décision : Ajoutez un petit endpoint de diagnostic temporaire ou journalisez les en-têtes forwardés au serveur web ; puis ajustez la configuration du proxy ou la prise en compte des proxies par WordPress (souvent via wp-config.php et des motifs de proxies de confiance).
Task 12: Check for “headers already sent” in PHP/WordPress logs
cr0x@server:~$ sudo tail -n 50 /var/log/php8.2-fpm.log | egrep -i 'headers already sent|warning|notice' | tail
WARNING: [pool www] child 18124 said into stderr: "PHP Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/plugins/bad-plugin/bad.php:1) in /var/www/html/wp-includes/pluggable.php on line 1427"
Ce que cela signifie : Un plugin a imprimé une sortie trop tôt, donc WordPress ne peut pas définir les cookies/en-têtes de façon fiable.
Décision : Désactivez le plugin fautif (Task 13) et corrigez/remplacez-le. Ne « contournez » pas cela ; c’est du code cassé.
Task 13: Disable plugins quickly without wp-admin
cr0x@server:~$ cd /var/www/html
cr0x@server:~$ sudo mv wp-content/plugins wp-content/plugins.disabled
cr0x@server:~$ sudo mkdir wp-content/plugins
cr0x@server:~$ sudo chown -R www-data:www-data wp-content/plugins
Ce que cela signifie : WordPress va démarrer sans plugins, ce qui restaure souvent la connexion. C’est brutal. Ça marche.
Décision : Si la connexion fonctionne maintenant, réintroduisez les plugins par lots pour trouver le coupable. Si c’est encore cassé, le problème est en dessous (proxy/cache/config).
Task 14: Check system time sync (for multi-node and expiry weirdness)
cr0x@server:~$ timedatectl status | sed -n '1,12p'
Local time: Sat 2025-12-27 11:08:42 UTC
Universal time: Sat 2025-12-27 11:08:42 UTC
RTC time: Sat 2025-12-27 11:08:42
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
Ce que cela signifie : La synchro temporelle est saine. Si ce n’est pas synchronisé (ou diffère entre nœuds), l’expiration des cookies et les vérifications de nonces peuvent échouer.
Décision : Réparez NTP/chrony avant d’aller plus loin. La dérive temporelle crée des problèmes d’auth « aléatoires » qui font perdre des jours.
Task 15: Verify the response isn’t compressing/transforming in a way that breaks headers (proxy sanity)
cr0x@server:~$ curl -skI https://www.example.com/wp-login.php | egrep -i 'content-encoding|set-cookie|vary'
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly; SameSite=Lax
vary: Accept-Encoding
Ce que cela signifie : Normal. Si vous voyez une altération d’en-têtes exotique ou des cookies manquants seulement lorsqu’une certaine fonctionnalité d’« optimisation » est activée, cette fonctionnalité est coupable jusqu’à preuve du contraire.
Décision : Désactivez la fonctionnalité de transformation d’en-têtes à l’edge et retestez. Puis réactivez avec des exclusions appropriées.
Task 16: Inspect browser-visible cookie attributes via a server-side reproduction (optional but decisive)
cr0x@server:~$ curl -skD - https://www.example.com/wp-login.php -o /dev/null | sed -n '/^Set-Cookie/Ip'
Set-Cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly; SameSite=Lax
Ce que cela signifie : Confirme les attributs exacts du cookie quittant le serveur. Si les navigateurs le rejettent encore, c’est généralement un décalage de domaine, un contexte tiers, ou une politique d’entreprise.
Décision : Comparez l’hôte demandé vs Domain/Path du cookie ; vérifiez l’intégration cross-site ; testez depuis un profil propre et depuis un autre réseau.
Trois mini-récits d’entreprise depuis le terrain
Mini-récit 1 : L’incident causé par une mauvaise hypothèse
L’entreprise avait une instance WordPress utilisée pour les communiqués de presse et les mises à jour investisseurs. Ce n’était pas « critique » jusqu’au jour où ça l’a été—le jour des résultats, l’équipe comms ne pouvait pas se connecter. Le site s’affichait bien en public, ce qui a fait supposer à la direction que c’était une « erreur utilisateur ». Classique.
L’ingénieur d’astreinte a vérifié l’évident : cookies activés, mode incognito, autre laptop. Même erreur. Ils ont récupéré les en-têtes avec curl et ont remarqué quelque chose de subtil : la réponse de la page de connexion n’avait pas de Set-Cookie à l’URL publique, mais en avait une en touchant l’origine directement.
La mauvaise hypothèse était que le CDN « ne faisait que mettre en cache les assets statiques ». Ce n’était pas le cas. Quelqu’un avait activé une règle pour mettre en cache « tout le HTML pour les performances », avec une exception pour /wp-admin mais pas pour /wp-login.php. Le CDN avait mis en cache une réponse de connexion qui n’établissait jamais un aller-retour de cookie valide, et il la servait fidèlement à tout le monde.
La correction a été simple : contourner la mise en cache pour les endpoints de connexion et d’administration, purger le cache, et ajouter une vérification de régression dans leur surveillance synthétique pour affirmer la présence de Set-Cookie sur la page de connexion. La leçon : les hypothèses sur des couches que vous touchez rarement coûtent cher quand elles cassent.
Mini-récit 2 : L’optimisation qui a mal tourné
Une autre organisation voulait réduire le Time To First Byte sur les pages PHP. Quelqu’un a déployé fastcgi_cache Nginx sur le cluster WordPress. Ça a très bien marché en staging. En production ça paraissait plus rapide. Les métriques se sont améliorées. Tout le monde s’est félicité et est allé déjeuner.
Deux jours plus tard, les éditeurs ont commencé à signaler des boucles de connexion intermittentes. Pas constantes. Pas reproductibles à la demande. Le pire genre de bug : celui qui fait débattre si c’est réel.
Finalement, un ingénieur a ajouté un en-tête X-Cache et a découvert que certaines réponses 302 autour de l’authentification étaient mises en cache dans des conditions imprévues. La clé de cache n’incluait pas assez de variation, et la logique de « skip cache » manquait un endpoint de connexion réécrit utilisé par un plugin de sécurité.
La correction a exigé de resserrer les règles de contournement de cache, d’exclure explicitement wp-login.php, wp-admin et tout alias de connexion, et de garantir que la présence de cookies force le bypass. Les performances sont restées majoritairement améliorées, mais l’équipe a appris une règle à garder : mettre en cache des flux d’auth dynamiques, c’est comme mettre un turbocompresseur sur un vélo—techniquement possible, socialement irresponsable.
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une entreprise faisait tourner WordPress derrière un load balancer et deux reverse proxies, pour la « conformité ». Ils avaient aussi une habitude qui semblait ennuyeuse : chaque changement de règles edge nécessitait un petit script de vérification avant déploiement.
Le script effectuait trois vérifications : fetch /wp-login.php et affirmer qu’un Set-Cookie existe ; fetch /wp-admin/ et s’assurer qu’il ne renvoie pas d’en-têtes cacheables ; et confirmer que les redirections mènent à un seul hôte canonique en HTTPS.
Une équipe de sécurité a poussé une mise à jour de leur template WAF. Elle a involontairement supprimé Set-Cookie des réponses correspondant à une signature générique de « cookie de tracking ». Cela aurait briqué la connexion admin sur une dizaine de sites.
Mais la pipeline de déploiement a bloqué le changement parce que la vérification a échoué en pré-production. La correction a été une exception WAF pour les cookies d’auth WordPress et une signature plus précise. Rien de spectaculaire n’est arrivé en production, ce qui est le meilleur genre d’incident. Leur garde-boue ennuyeux a sauvé la mise en empêchant une panne que personne n’aurait su expliquer lors d’une réunion de direction.
Erreurs courantes : symptôme → cause → correction
Cette section est la liste « arrêtez de deviner ». Si vous voyez le symptôme, allez directement à la cause probable et appliquez la correction. Évitez les étapes cargo‑cultes.
1) Symptom: “Cookies are blocked” appears immediately after submitting credentials
- Root cause:
Set-Cookien’atteint jamais le navigateur (supprimé par CDN/WAF/proxy) ou en-têtes déjà envoyés dans PHP. - Fix: Comparez les en-têtes edge vs origine ; désactivez le cache CDN pour la connexion ; vérifiez les logs PHP‑FPM pour « Cannot modify header information ».
2) Symptom: Infinite redirect loop between /wp-admin and /wp-login.php
- Root cause: Mismatch scheme/host (
siteurl/homedésalignés), ou proxy qui rapporte mal HTTPS. - Fix: Alignez
homeetsiteurl; assurez-vous queX-Forwarded-Protoest correct ; imposez un seul nom d’hôte canonique.
3) Symptom: Works on origin, fails on public domain
- Root cause: Couche edge réécrivant/supprimant
Set-Cookie, mise en cache des réponses de connexion, ou protection anti-bot agressive. - Fix: Contournez le cache pour
/wp-login.phpet/wp-admin; désactivez la mise en cache HTML ; ajoutez une exception WAF pour ces chemins.
4) Symptom: Works in one browser/profile but not another
- Root cause: Vieux cookies avec Domain/Path non correspondants, extension de navigateur qui altère les requêtes, ou politiques d’entreprise strictes.
- Fix: Inspectez le stockage des cookies pour le domaine ; supprimez seulement les cookies WordPress ; testez dans un profil propre ; vérifiez si la connexion est intégrée/cross-site.
5) Symptom: Only some users can log in, often behind corporate networks
- Root cause: Proxy d’entreprise qui supprime des en-têtes, interception TLS, ou politique bloquant les cookies dans certains contextes.
- Fix: Capturez les en-têtes depuis les réseaux affectés ; fournissez une connexion non intégrée ; assurez que les cookies sont first-party et utilisez HTTPS de façon cohérente.
6) Symptom: Breaks after enabling “force HTTPS” at the edge
- Root cause: WordPress pense encore être en HTTP, génère des redirections/cookies incorrects, ou crée des URLs mixtes.
- Fix: Transmettez correctement les en-têtes HTTPS et configurez WordPress pour reconnaître HTTPS derrière des proxies ; alignez les URLs DB.
7) Symptom: Multisite login failures across subdomains
- Root cause: Portée du domaine cookie non adaptée à la configuration réseau, plus une canonicalisation incohérente entre sites.
- Fix: Assurez un mapping de domaines cohérent ; évitez de mélanger modes sous‑domaine et sous‑répertoire par erreur ; vérifiez les réglages réseau et le comportement de domaine cookie.
8) Symptom: Random “logged out” behavior after login succeeds
- Root cause: Cache mixant états authentifiés et non authentifiés, ou dérive temporelle entre nœuds, ou collisions de cache d’objets.
- Fix: Assurez que les caches contournent les requêtes avec cookies d’auth ; vérifiez NTP ; validez la configuration du cache d’objets et les salts.
Listes de vérification / plan étape par étape
Checklist A: One-pass triage (15 minutes)
- Reproduire dans un profil de navigateur propre. Notez l’URL exacte et si vous utilisez www ou l’apex.
- Vérifier les en-têtes sur
/wp-login.phpà l’URL publique : confirmer la présence deSet-Cookieet quecache-controln’est pas public. - Vérifier la chaîne de redirections pour
/wp-admin/. Confirmer qu’elle aboutit à un hôtehttps://canonique unique. - Contourner l’edge (joindre l’origine/LB directement) et comparer le comportement de
Set-Cookie. - Désactiver les plugins si les logs montrent « headers already sent » ou si le comportement varie par requête.
Checklist B: Make the fix durable (the “won’t page me again” plan)
- Canonicaliser hôte et schéma : choisissez un seul (généralement
https://wwwouhttps://apex) et appliquez‑le partout. - Verrouiller les règles de cache :
- Ne mettez jamais en cache
/wp-login.php,/wp-admin/ou les réponses qui définissent des cookies d’auth. - Contournez le cache quand la requête a des cookies d’auth WordPress.
- Ne mettez pas en cache les 302/301 issus des endpoints d’auth sauf si vous comprenez profondément l’impact.
- Ne mettez jamais en cache
- Rendre corrects les en-têtes proxy : assurez-vous que HTTPS est correctement signalé à l’origine et que seuls les proxies de confiance peuvent définir les en-têtes forwardés.
- Ajouter des vérifications synthétiques qui affirment :
Set-Cookieexiste sur/wp-login.php- pas d’en-têtes de cache public sur login/admin
- la chaîne de redirection aboutit à l’hôte canonique
- Minimiser les plugins qui touchent à la connexion. Beaucoup sont acceptables, mais tout ce qui touche en-têtes, redirections ou cookies doit être traité comme du middleware de production.
- Garder les horloges synchronisées entre nœuds, toujours.
Checklist C: If you must change something during an incident
- Purger le cache CDN pour
/wp-login.phpet/wp-admin/(et tout alias de connexion). - Désactiver temporairement la mise en cache HTML/fonctionnalités d’optimisation edge pour ces chemins.
- Désactiver les plugins en renommant le répertoire plugins (rollback rapide).
- Revenir sur le dernier changement edge/WAF/template si cela a commencé « juste après » un déploiement.
FAQ
1) Is WordPress lying when it says cookies are blocked?
Il ne ment pas, il est vague. WordPress ne peut pas confirmer l’aller‑retour du cookie, donc il blâme les « cookies » même si le vrai problème est votre proxy ou votre cache.
2) Why does it work for public pages but not wp-admin?
Les pages publiques peuvent être mises en cache et ne nécessitent pas de session authentifiée. La connexion oui. Tout ce qui casse Set-Cookie, les redirections, ou la détection HTTPS se manifeste d’abord dans wp-admin.
3) Can a CDN really break WordPress login?
Oui. S’il met en cache /wp-login.php, met en cache des redirections dans la chaîne de connexion, supprime Set-Cookie, ou applique une protection bot qui bloque les POSTs, vous aurez des échecs de cookie/connexion.
4) What’s the single most common cause in modern setups?
La mise en cache ou « optimisation » appliquée aux endpoints login/admin. En deuxième place : terminaison HTTPS/proxy qui ne relaie pas correctement les en-têtes à WordPress.
5) Do I need to change SameSite settings?
Pas généralement pour les connexions WordPress standard. Pensez à SameSite si vous avez du SSO cross-domain, une connexion intégrée, ou des callbacks externes. Si vous le changez, testez sur plusieurs navigateurs et ne devinez pas.
6) Why does changing home and siteurl fix it?
Parce que WordPress utilise ces valeurs pour générer des URLs et parfois pour inférer la portée des cookies. Si l’un indique example.com et l’autre www.example.com, vous invitez des incompatibilités de cookie et des boucles de redirection.
7) I disabled all plugins and it still fails. Now what?
Alors c’est probablement l’infrastructure : cache edge, réécriture d’en-têtes, détection HTTPS, ou décalage d’URL en base. Comparez les en-têtes edge vs origine et vérifiez la chaîne de redirections.
8) Could time drift really cause login trouble?
Oui, surtout dans des environnements multi‑nœuds. Les cookies, nonces et validations de session peuvent se comporter comme si le cookie était « ignoré » lorsque les horodatages ne concordent pas.
9) Should I just tell users to clear cookies?
Seulement comme solution de contournement temporaire et seulement après avoir collecté des preuves. Si vider les cookies « règle » le problème, vous avez encore un décalage systémique ou un problème de cache prêt à ressurgir.
10) What if the error only appears on mobile or inside an embedded webview?
Vous avez peut‑être des restrictions sur les cookies tiers, des politiques de navigateur in-app, ou des flux cross-site. Évitez la connexion intégrée, gardez‑la first‑party, et vérifiez les attributs des cookies pour ce contexte.
Conclusion : prochaines étapes durables
« Les cookies sont bloqués » est la façon qu’a WordPress de dire qu’une poignée de session a échoué. Votre travail est de déterminer quelle couche a menti : l’application, le proxy, le cache, ou la configuration. Le chemin le plus rapide est fondé sur des preuves, pas sur des impressions : capturez les en-têtes, comparez edge vs origine, inspectez les redirections et confirmez le schéma/hôte canonique.
Faites ceci ensuite, dans l’ordre :
- Exécutez une vérification d’en-têtes sur
/wp-login.phpet confirmezSet-Cookieet l’absence de cache public. - Suivez la chaîne de redirection pour
/wp-admin/et éliminez les hôtes/schémas mixtes. - Contournez votre edge et comparez. Si l’origine fonctionne, corrigez les règles edge (cache et gestion des en-têtes).
- Si vous voyez « headers already sent », désactivez le plugin fautif et traitez‑le comme un défaut de code, pas une bizarrerie de configuration.
- Ajoutez une petite vérification synthétique pour que vous n’appreniez jamais ce problème via un dirigeant frustré.