Нічого так не підвищує тиск, як повідомлення від керівника: «Я не можу увійти в WordPress. Видає, що файли cookie заблоковано.» Ви пробуєте самі — та ж помилка. Відкриваєте DevTools і… браузер виглядає в порядку. Cookie працюють скрізь. То чому WordPress поводиться так, ніби це 2004 рік?
Це повідомлення — не діагноз. Це WordPress, який зменшує плечі в плащі. Справжня проблема майже завжди одна з цих: заголовки не доходять до браузера, неправильно визначено HTTPS, кеш повертає невірну відповідь або проксі/CDN переписує все в маячню. Розглянемо це як інцидент: відтворити, зібрати докази, ізолювати шар, виправити причину і додати захисні механізми, щоб це не повернулося о 2 ночі.
Що насправді означає повідомлення (і чого воно не означає)
Коли WordPress показує «Файли cookie заблоковано або ваш браузер їх не підтримує», це рідко проблема браузера. WordPress показує це, коли потік входу не може підтвердити круговий обмін сесійним cookie.
Простіше кажучи, WordPress очікує таку послідовність:
- Ваш браузер запитує
/wp-login.php. - Сервер відповідає заголовком
Set-Cookie(тестовий cookie або auth cookie залежно від кроку). - Ваш браузер надсилає цей cookie назад у наступному запиті.
- WordPress бачить cookie і продовжує. Якщо ні — ви отримуєте повідомлення «файли cookie заблоковано» або цикл перенаправлень.
Якщо cookie не повертається, WordPress не може сказати, чи ви аутентифіковані, чи ваш браузер взагалі може зберігати cookie, або чи запит входу не відтворюється з кешу. Тоді WordPress підкидає це узагальнене повідомлення.
Чого це зазвичай не є
- Не налаштування браузера, якщо тільки ви не в дуже суворому середовищі або не тестуєте у незвичному режимі конфіденційності.
- Не «WordPress упав». Більшість сайтів і далі коректно віддають сторінки; зломлений лише вхід.
- Не постійне вирішення через «очистіть cookie і спробуйте знову». Якщо очищення cookie допомагає, це підказка, а не вирішення.
Що це зазвичай є
- Заголовки змінені або видалені (proxy/CDN/WAF, неправильно налаштований PHP-FPM, невірні правила кешування).
- Плутанина HTTP/HTTPS (WordPress думає, що працює по HTTP, встановлює cookie без Secure або генерує перенаправлення неправильно).
- Невідповідність області cookie (домени/шляхи не збігаються, неправильні
siteurlіhome, змішані імена хостів). - Взаємодія кешу (page cache, reverse proxy cache, object cache або CDN кешує
/wp-login.phpабо відповіді з перенаправленням). - Плагін/шар безпеки, що перевищує повноваження (переписує заголовки, вставляє перенаправлення, погано змінює політики SameSite).
Парафразуючи ідею Вернера Вогеляса (CTO Amazon): Все іноді ламається; будуйте системи й звички, які очікують відмов і швидко відновлюються.
Це підходить і тут. Ставте вхід у критичний шлях. Спостерігайте за ним, захищайте його і не дозволяйте «очищенню cookie» стати вашим оперативним планом.
Перевірка реальності cookie: факти та коротка історія
Cookie виглядають дрібними, але скільки хаосу вони можуть спричинити. Кілька конкретних фактів дадуть кращу інтуїцію під час усунення неполадок.
- Факт 1: HTTP за дизайном безстанний. Cookie були прагматичним хаком, щоб зберегти стан між запитами без перепроектування вебу.
- Факт 2: Cookie з’явилися ще в епоху Netscape (середина 1990-х). Вони були корисні до того, як стали контроверсійними.
- Факт 3: Cookie — це просто заголовок. Сервер надсилає
Set-Cookie, клієнт повертаєCookie. Якщо проксі маніпулює заголовками, ваша «проблема браузера» — насправді інфраструктурна. - Факт 4: Сучасні браузери суворіше виконують правила cookie — особливо щодо
SameSite, крос-сайтових запитів та контекстів third-party. - Факт 5: Атрибут
Secureблокує cookie через HTTP. Добре для безпеки. Погано при неправильно налаштованому TLS-термінуванні, коли додаток думає, що він на HTTP. - Факт 6: Багато багів входу проявляються як цикли перенаправлень, а не явні помилки cookie, бо додаток постійно намагається встановити сесію.
- Факт 7: WordPress історично толерував багато дивних хостинг-настроювань (shared hosting, випадкові порти, дивні проксі). Така спадщина означає багато способів налаштувати одне й те саме — й багато шляхів помилитися.
- Факт 8: Деякі CDN і плагіни «оптимізації» агресивно кешують перенаправлення й HTML. Якщо вони кешують відповіді
wp-login.php, ви фактично віддаєте заздалегідь згенерований потік входу усім. Це не «оптимізація»; це рулетка.
Жарт №1: Cookie — це крихітні файли, що можуть зіпсувати ваш вихідні. Другий за неприємністю тип cookie у продакшені — той, що ви не встановлювали.
Швидкий план діагностики (перший/другий/третій)
Якщо ви довго займаєтеся SRE, ви привчаєтеся до хорошого плану дій. Ось такий, що швидко знайде винуватця без блукань по налаштуваннях плагінів, ніби це будинок з привидами.
Перший: Доведіть, чи надсилається і повертається Set-Cookie
- Захопіть заголовки відповіді з
/wp-login.phpі POST на/wp-login.php. - Підтвердьте, що браузер (або curl) надсилає cookie назад у наступному запиті.
- Якщо
Set-Cookieвідсутній або змінюється непередбачувано між стрибками, перестаньте звинувачувати браузер.
Другий: Визначте «edge», який володіє заголовками
- Чи є CDN? WAF? Реверс-проксі? Ingress-контролер? Nginx шар кешування?
- Обійдіть його тимчасово (безпосередньо origin IP/порт, hosts-файл, внутрішня мережа) і порівняйте заголовки.
- Якщо origin працює, а edge ламається — у вас підозрюваний.
Третій: Перевірте HTTPS і уявлення про канонічний хост
- WordPress має погоджуватися з реальністю щодо: схеми (https), хоста (www vs apex) і шляху.
- Перевірте
siteurlіhomeу базі даних. - Перевірте проксі-заголовки:
X-Forwarded-Proto,X-Forwarded-Hostта значення$_SERVERу WordPress.
Коли негайно ескалювати
- Ви бачите кешовані відповіді для
/wp-login.phpабо/wp-admin/. Set-Cookieзаголовки видаляються або переписуються на edge.- Сайт за NAT/SSO, корпоративним проксі або нещодавно змінилася сувора політика CSP.
Кореневі причини, які ви справді можете виправити
1) Неправильна схема або хост: WordPress встановлює cookie не туди
Якщо WordPress думає, що працює на http://, а користувачі підключаються через https://, cookie можуть бути видані без потрібних атрибутів, перенаправлення можуть некоректно обертатися, і auth cookie може ніколи не прийнятися.
Поширені сценарії:
- TLS терміновано на балансувальнику навантаження, але origin не отримує
X-Forwarded-Proto: https. - Ви примушуєте HTTPS на edge, але WordPress всередині все ще генерує HTTP URL.
- Змішані канонічні імена хостів: форма входу відправляє на
example.com, але cookie налаштовано дляwww.example.com(або навпаки).
2) Шари кешування: вхід не слід «оптимізувати»
Будь-який кеш, який зберігає або відтворює відповіді входу, може ламати cookie. Це включає:
- Правила CDN, які випадково охоплюють
/wp-login.php. - Nginx
fastcgi_cache, застосований занадто широко. - Плагіни кешування WordPress, що кешують адмін або сторінки входу.
- Правила на краю, які занадто агресивно кешують 301/302 відповіді.
Вхід — динамічний. Аутентифікація — для кожного користувача. Якщо ви кешуєте це, ви не пришвидшуєте сайт; ви ламаєте базову реальність.
3) SameSite і Secure атрибути: сучасні браузери стали суворішими
Сучасні правила cookie жорсткіші щодо крос-сайтових контекстів. Більшість входів WordPress — першопартійні, тож ви звичайно уникаєте проблем SameSite. Але вартості проблем з’являються, коли додаєте:
- вбудовані фрейми для входу,
- SSO потоки,
- OAuth плагіни з крос-доменними callback,
- або «вхід з іншого домену» налаштування,
…тоді cookie можуть відхилятися, якщо атрибути не встановлені правильно.
4) Невідповідність домену/шляху cookie через дрейф конфігурації
WordPress має кілька способів визначити домен і шлях для cookie. Якщо ваші WP_HOME, WP_SITEURL, значення у базі і фактичний URL доступу не збігаються, ви легко можете встановити cookie для неправильного домену або шляху.
5) Плагіни безпеки, WAF та «жорсткі» налаштування, що руйнують заголовки
Продукти безпеки люблять переписувати заголовки. Інколи вони роблять це правильно. Інколи вони видаляють Set-Cookie з міркувань «приватності». Або вставляють перенаправлення, які втрачають cookie. Або блокує POST на /wp-login.php під надто широкими правилами.
6) Вивід PHP перед заголовками (так, це все ще трапляється)
Якщо щось виводить контент перед тим, як WordPress встановить cookie, PHP може видати поведінку «headers already sent», що означає: ваш Set-Cookie ніколи не покидає сервер. Це часто трапляється з поламаними темами, кастомними правками wp-config.php або плагінами, які виводять пробіли/BOM на початку файлу.
7) Розбіжність часу і дивна поведінка TTL
Термін дії cookie залежить від часу. Якщо на серверах є розбіжність часу, cookie можуть виглядати одразу простроченими — особливо у мульти-нодових налаштуваннях, де один вузол виписує, а інший перевіряє. Це рідше, але реально.
Жарт №2: Синхронізація часу — тихий вбивця, бо рідко щось говорить «безпечний вхід», як сервер, що живе у майбутньому.
Практичні завдання: команди, виводи та рішення
Нижче — практичні завдання, які можна виконати з хоста з мережею до сайту (або з самого веб-сервера). Кожне містить реалістичний приклад виводу і рішення, яке ви приймаєте на його підставі. Виконуйте по порядку, якщо хочете чистий доказовий ланцюжок.
Завдання 1: Забрати заголовки /wp-login.php і підтвердити наявність Set-Cookie
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
Що це означає: WordPress віддає тестовий cookie; це добре. Якщо ви не бачите set-cookie зовсім, або заголовки зрізані upstream, або PHP їх не надсилає.
Рішення: Якщо відсутній — обійдіть CDN/проксі далі (Завдання 3). Якщо присутній — підтвердіть, що він повертається (Завдання 2).
Завдання 2: Підтвердити круговий обмін cookie за допомогою 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
Що це означає: curl зберіг і відправив cookie успішно. Якщо сервер все ще скаржиться в браузері — проблема може бути в кешах, перенаправленнях або невідповідності хоста/схеми у шляху браузера.
Рішення: Якщо круговий обмін curl працює, але браузери падають — перевірте перенаправлення і канонізацію доменів (Завдання 4–6).
Завдання 3: Обійти CDN/реверс-проксі, звернувшись до origin (або внутрішнього LB) напряму
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
Що це означає: Origin ставить cookie, але помітте, що він відсутній Secure при HTTP. Якщо користувачі заходять через HTTPS на edge, WordPress може потребувати вказівки, що він працює через HTTPS, щоб встановити правильні атрибути й URL.
Рішення: Виправте виявлення HTTPS за проксі (див. Завдання 10–11) і переконайтесь, що edge пересилає X-Forwarded-Proto.
Завдання 4: Перевірити ланцюжок перенаправлень для входу та адмінки
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
Що це означає: Перенаправлення очікувані, але зверніть увагу на cache-control: max-age=3600 на канонічному перенаправленні. Якщо CDN кешує цей 301/302 агресивно для шляхів входу, ви можете застрягнути в циклі або отримувати застарілі відповіді.
Рішення: Додайте правила «не кешувати» для /wp-login.php, /wp-admin/ і пов’язаних auth-перенаправлень на CDN/проксі.
Завдання 5: Перевірити siteurl і home в базі даних
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|
+-------------+------------------------+
Що це означає: Змішані імена хостів. Це класичний генератор невідповідності області cookie і може породити цикли входу.
Рішення: Зробіть їх однаковими для канонічного хоста (зазвичай обидва https://www.example.com або обидва apex). Оновіть обережно (Завдання 6) і забезпечте узгоджені перенаправлення.
Завдання 6: Виправити home і siteurl (обережно)
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 |
+-------------+-----------------------+
Що це означає: Канонічний хост вирівняно. Це часто вирішує дивну поведінку області cookie та цикли перенаправлень.
Рішення: Повторно протестуйте вхід. Якщо досі не працює — переходьте до інспекції заголовків на edge (Завдання 7) і перевірок кешу (Завдання 8).
Завдання 7: Порівняйте Set-Cookie і заголовки кешу edge vs origin
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
Що це означає: CDN повертає hit на /wp-login.php. Це не підказка — це вирва з димом.
Рішення: Негайно припиніть кешування шляхів входу й адмінки на CDN і очистіть кешовані обʼєкти. Потім повторно протестуйте.
Завдання 8: Перевірити конфіг Nginx на предмет кешування шляхів входу/адмінки
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;
}
}
Що це означає: Ця конфігурація робить правильно: вона пропускає кеш для входу/адмінки. Якщо у вашій конфігурації відсутні ці виключення, ви можете зламати аутентифікацію.
Рішення: Якщо відсутні — додайте виключення і перезавантажте Nginx. Якщо присутні — перевірте, чи карта дійсно співпадає з вашими шляхами (деякі налаштування використовують інші префікси або перезаписи).
Завдання 9: Перевірити, чи відповіді входу/адмінки кешуються все одно
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
Що це означає: no-store і x-cache: MISS — це здорово. Якщо ви бачите HIT або публічні заголовки кешування, виправляйте правила кешу перш за все.
Рішення: Якщо кеш чистий — зосередьтесь на схемі/forwarded заголовках і атрибутах cookie.
Завдання 10: Перевірити, чи реверс-проксі пересилає індикацію HTTPS
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;
Що це означає: Проксі пересилає схему, яку бачить. Якщо TLS термінує вище цього проксі, $scheme може бути http навіть для користувацького HTTPS — і це неправильно.
Рішення: Якщо TLS термінує на upstream load balancer, встановіть там X-Forwarded-Proto https, або пропускайте оригінальний заголовок і довіряйте йому з обережністю.
Завдання 11: Підтвердити, що WordPress бачить HTTPS на 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,
)
Що це означає: У цьому shell-контексті ви не маєте заголовків запиту, але це підказує, що саме треба шукати в реальному контексті запиту: WordPress покладається на серверні змінні. Якщо запити не заповнюють їх, WordPress може неправильно працювати за проксі.
Рішення: Додайте невеликий тимчасовий діагностичний ендпоінт або логування forwarded-заголовків на вебсервері; потім налаштуйте проксі або обізнаність WordPress про проксі (зазвичай через wp-config.php і шаблони довірених проксі).
Завдання 12: Перевірити логи PHP/WordPress на «headers already sent»
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"
Що це означає: Плагін вивів контент занадто рано, тож WordPress не може надійно встановлювати cookie/заголовки.
Рішення: Відключіть проблемний плагін (Завдання 13) і виправте/замініть його. Не «працюйте навколо» — це поламаний код.
Завдання 13: Швидко відключити плагіни без 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
Що це означає: WordPress запуститься без плагінів, що часто достатньо, щоб відновити вхід. Це грубий підхід. Він працює.
Рішення: Якщо вхід тепер працює — поверніть плагіни по групах, щоб знайти винуватця. Якщо все ще не працює — проблема нижче (проксі/кеш/конфіг).
Завдання 14: Перевірити синхронізацію часу системи (для мульти-нод та дивної поведінки TTL)
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
Що це означає: Синхронізація часу здорова. Якщо вона не синхронізована (або відрізняється між вузлами), термін дії cookie і перевірки nonce можуть спрацювати неправильно.
Рішення: Виправте NTP/chrony до того, як будете копати глибше. Дрейф часу створює «випадкові» проблеми аутентифікації, які забирають дні.
Завдання 15: Підтвердити, що відповідь не компресується/не трансформується так, щоб ламати заголовки (перевірка проксі)
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
Що це означає: Нормально. Якщо ви бачите екзотичне спотворення заголовків або відсутні cookie тільки коли ввімкнена певна «оптимізація», ця функція — підозрювана.
Рішення: Вимкніть функцію трансформації заголовків на edge і повторно протестуйте. Потім увімкніть з правильними виключеннями.
Завдання 16: Переглянути видимі в браузері атрибути cookie через відтворення на сервері (опціонально, але переконливо)
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
Що це означає: Підтверджує точні атрибути cookie, що виходять із сервера. Якщо браузери все ще відхиляють — зазвичай причина в невідповідності домену, third-party контексті або корпоративній політиці.
Рішення: Порівняйте запитуваний хост з Domain/Path cookie; перевірте на крос-сайтове вбудовування; протестуйте з чистого профілю та з іншої мережі.
Три корпоративні міні-історії з фронту
Міні-історія 1: Інцидент через хибне припущення
Компанія мала інстанс WordPress для пресрелізів і оновлень інвесторів. Він не здавався «критичним», поки ним не став — у день оголошення прибутків команда комунікацій не могла зайти. Сайт публічно рендерився нормально, через що керівництво думало, що це «помилка користувача». Класика.
Розмінний інженер перевірив очевидне: cookie в браузері — ввімкнені, інкогніто, інший ноутбук. Та ж помилка. Вони зняли заголовки через curl і помітили тонку деталь: відповідь сторінки входу не мала Set-Cookie на публічному URL, але мала при зверненні напряму до origin.
Хибне припущення було в тому, що CDN «лише кешує статичні ресурси». Ні. Хтось увімкнув правило кешувати «весь HTML для продуктивності», з винятком /wp-admin, але не для /wp-login.php. CDN закешував відповідь входу, яка ніколи не встановлювала валідний круговий обмін cookie, і віддавав її всім.
Виправлення було простим: припинити кешування для шляхів входу й адмінки, очистити кеш і додати регресійну перевірку в синтетичному моніторингу, яка б асертувала наявність Set-Cookie на вході. Урок: припущення про шари, якими ви рідко опікуєтеся, дорогі, коли вони ламаються.
Міні-історія 2: Оптимізація, що відбилася бумерангом
Інша організація хотіла пришвидшити Time To First Byte для PHP-сторінок. Хтось розкатив Nginx fastcgi_cache на WordPress-кластері. У стаджингу все було добре. Продукція виглядала швидшою. Метрики покращилися. Усі похвалилися і пішли обідати.
Через два дні редактори почали повідомляти про періодичні цикли входу. Не постійні. Не відтворювані на вимогу. Найгірший тип багу: той, що змушує сперечатися, реальний він чи ні.
Зрештою інженер додав заголовок X-Cache і виявив, що певні 302 відповіді навколо аутентифікації кешуються за умов, яких не очікували. Ключ кешу не мав достатньої варіації, а логіка «skip cache» пропустила переписаний endpoint входу, який використовував плагін безпеки.
Виправлення вимагало посилення правил обходу кешу, явного виключення wp-login.php, wp-admin і всіх псевдонімів входу, і забезпечення того, щоб наявність cookie в запиті форсувала обхід кешу. Продуктивність здебільшого залишилася, але команда винесла правило: кешувати динамічні auth-потоки — як поставити турбокомпресор на велосипед: технічно можливо, соціально безвідповідально.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Одне підприємство запускало WordPress за балансувальником навантаження і двома реверс-проксі через «комплаєнс». У них також була нудна, але корисна звичка: кожна зміна правил на edge вимагала пройти невеликий верифікаційний скрипт перед релізом.
Скрипт робив три перевірки: забрати /wp-login.php і асертувати наявність Set-Cookie; забрати /wp-admin/ і впевнитися, що він не повертає кешовані заголовки; і підтвердити, що перенаправлення ведуть до одного канонічного хоста і HTTPS.
Команда безпеки розгорнула оновлення до шаблону WAF. Воно ненавмисно зрізало Set-Cookie для відповідей, що відповідали загальній сигнатурі «tracking cookie». Це могло вивести з ладу вхід у адмінку десятків сайтів.
Але пайплайн розгортання заблокував зміну, бо верифікація провалилася в преконфігурації. Виправлення — виняток у WAF для WordPress auth cookie і більш точна сигнатура. У продукції нічого драматичного не сталося — і це найкращий тип інциденту. Їхня нудна перевірка врятувала день, не давши зламу, про який ніхто не зміг би пояснити лідерам.
Поширені помилки: симптом → коренева причина → виправлення
Цей розділ — список «перестаньте гадати». Якщо ви бачите симптом, переходьте до ймовірної кореневої причини і робіть виправлення. Уникайте ритуальних дій.
1) Симптом: «Файли cookie заблоковано» з’являється відразу після відправки даних входу
- Коренева причина:
Set-Cookieніколи не доходить до браузера (зрізане CDN/WAF/проксі) або заголовки вже надіслані в PHP. - Виправлення: Порівняйте edge vs origin заголовки; відключіть кеш CDN для входу; перевірте логи PHP-FPM на «Cannot modify header information».
2) Симптом: Нескінченний цикл перенаправлень між /wp-admin і /wp-login.php
- Коренева причина: Невідповідність схеми/хоста (
siteurl/homeнеузгоджені), або проксі неправильно вказує HTTPS. - Виправлення: Вирівняйте
homeіsiteurl; забезпечте правильнийX-Forwarded-Proto; зафіксуйте один канонічний хост.
3) Симптом: Працює на origin, не працює на публічному домені
- Коренева причина: Шар edge переписує/зрізає
Set-Cookie, кешує відповіді входу або застосовує агресивний захист від ботів. - Виправлення: Обійдіть кеш для
/wp-login.phpі/wp-admin; вимкніть кешування HTML; додайте виняток WAF для цих шляхів.
4) Симптом: Працює в одному браузері/профілі, але не в іншому
- Коренева причина: Старі cookie з невідповідним Domain/Path, або розширення браузера змінює запити, або сувора корпоративна політика.
- Виправлення: Перегляньте збереження cookie для домену; видаліть лише WordPress cookie; протестуйте в чистому профілі; перевірте, чи не вбудовано вхід крос-сайтово.
5) Симптом: Тільки деякі користувачі можуть увійти, часто за корпоративними мережами
- Коренева причина: Корпоративний проксі зрізає заголовки, TLS-interception або політика блокує cookie в певних контекстах.
- Виправлення: Захопіть заголовки з уражених мереж; надайте не вбудований шлях для входу; забезпечте, щоб cookie були першопартійними і завжди через HTTPS.
6) Симптом: Ламається після ввімкнення «force HTTPS» на edge
- Коренева причина: WordPress все ще думає, що він на HTTP, встановлює невірні перенаправлення/cookie або генерує змішані URL.
- Виправлення: Пересилайте HTTPS заголовки правильно і налаштуйте WordPress розпізнавати HTTPS за проксі; вирівняйте URL в БД.
7) Симптом: Помилки входу в мультисайті на піддоменах
- Коренева причина: Область домену cookie не співпадає з налаштуваннями мережі, плюс непослідовна канонізація між сайтами.
- Виправлення: Забезпечте консистентне мапування доменів; не змішуйте випадково subdomain і subdirectory режими; перевірте налаштування мережі і поведінку домену cookie.
8) Симптом: Випадкові «виходи з сесії» після успішного входу
- Коренева причина: Кеш змішує автентифіковані й неавтентифіковані стани, або дрейф часу між вузлами, або колізії object cache.
- Виправлення: Переконайтесь, що кеш обходиться при наявності auth-cookie; перевірте NTP; валідовайте конфіг object cache і salts.
Контрольні списки / покроковий план
Контрольний список A: Первинна триаж-перевірка (15 хвилин)
- Відтворіть у чистому профілі браузера. Зафіксуйте точний URL і чи використовуєте ви www або apex.
- Перевірте заголовки на
/wp-login.phpна публічному URL: підтвердіть наявністьSet-Cookieі щоcache-controlне публічний. - Перевірте ланцюжок перенаправлень для
/wp-admin/. Підтвердіть, що він приводить до одного канонічного хоста зhttps://. - Обійдіть edge (зверніться напряму до origin/LB) і порівняйте поведінку
Set-Cookie. - Вимкніть плагіни, якщо в логах видно «headers already sent» або якщо поведінка змінюється між запитами.
Контрольний список B: Зробити виправлення стійким (план «не дзвоніть мені опівночі»)
- Канонізуйте хост і схему: оберіть один (зазвичай
https://wwwабоhttps://apex) і використовуйте скрізь. - Закріпіть правила кешування:
- Ніколи не кешуйте
/wp-login.php,/wp-admin/або відповіді, що встановлюють auth-cookie. - Обходьте кеш, коли запит має WordPress auth-cookie.
- Не кешуйте 302/301 з auth endpoint, якщо ви не розумієте всю зону ураження.
- Ніколи не кешуйте
- Забезпечте правильні проксі-заголовки: HTTPS має правильно сигналізуватися origin, і лише довірені проксі можуть встановлювати forwarded-заголовки.
- Додайте синтетичні перевірки, які асертують:
Set-Cookieіснує на/wp-login.php- немає публічних заголовків кешування на login/admin
- ланцюжок перенаправлень закінчується на канонічному хості
- Мінімізуйте плагіни для «тюнінгу входу». Багато з них ок, але все, що торкається заголовків, перенаправлень або cookie, слід ставити як продакшн-мідлвар.
- Тримайте годинники синхронними між вузлами — завжди.
Контрольний список C: Якщо потрібно змінювати щось під час інциденту
- Очистіть CDN-кеш для
/wp-login.phpі/wp-admin/(і всіх псевдонімів входу). - Тимчасово вимкніть кешування HTML/функції оптимізації на edge для цих шляхів.
- Вимкніть плагіни, перейменувавши директорію plugins (швидкий відкат).
- Відкочуйте останню зміну edge/WAF/template, якщо це почалося «одразу після» деплою.
FAQ
1) Чи обманює WordPress, коли каже, що cookie заблоковано?
Він не обманює, він просто невизначений. WordPress не може підтвердити круговий обмін cookie, тож він звинувачує «cookie», навіть якщо справжня проблема — проксі або кеш.
2) Чому публічні сторінки працюють, а wp-admin — ні?
Публічні сторінки можна кешувати і їм не потрібна сесія. Вхід потребує сесії. Все, що ламає Set-Cookie, перенаправлення або виявлення HTTPS, перш за все проявиться в wp-admin.
3) Чи може CDN дійсно зламати вхід WordPress?
Так. Якщо він кешує /wp-login.php, кешує перенаправлення в ланцюжку входу, зрізає Set-Cookie або застосовує захист, що блокує POST, ви отримаєте проблеми з cookie/входом.
4) Що найчастіша причина в сучасних налаштуваннях?
Кешування або «оптимізація», застосована до шляхів входу/адмінки. Друга за частотою причина: термінування HTTPS/проксі не передає заголовки коректно до WordPress.
5) Чи потрібно змінювати налаштування SameSite?
Зазвичай ні, для стандартних входів WordPress. Розгляньте SameSite, коли у вас крос-доменний SSO, вбудований вхід або зовнішні callback-и. Якщо змінюєте — тестуйте у різних браузерах і не гадьте.
6) Чому зміна home і siteurl це вирішує?
Бо WordPress використовує ці значення для генерації URL і іноді для виведення області cookie. Якщо одне каже example.com, а інше — www.example.com, ви запрошуєте невідповідності cookie і цикли перенаправлень.
7) Я відключив усі плагіни і все ще не працює. Що тепер?
Тоді, ймовірно, справа в інфраструктурі: кеш edge, перепис заголовків, виявлення HTTPS або невідповідність URL у базі. Порівняйте edge vs origin заголовки і перевірте ланцюжки перенаправлень.
8) Чи може дрейф часу справді викликати проблеми входу?
Так, особливо у мульти-нодових середовищах. Cookie, nonce і валідація сесій можуть поводитися так, ніби cookie «ігноруються», коли часові позначки не збігаються.
9) Чи просто сказати користувачам очистити cookie?
Лише як тимчасовий обхід і лише після того, як ви зібрали докази. Якщо очищення cookie «вирішує» — у вас все ще є системний дрейф або проблема кешування, що чекає на повторення.
10) Що робити, якщо помилка з’являється лише на мобільних або в вбудованому webview?
Тоді, можливо, ви маєте обмеження third-party cookie, політику in-app браузера або крос-сайтові потоки. Уникайте вбудованого входу, тримайте його першопартійним і перевіряйте атрибути cookie для такого контексту.
Висновок: наступні кроки, які працюють
«Файли cookie заблоковано» — це спосіб WordPress сказати, що рукопотиск сесії не пройшов. Ваше завдання — з’ясувати, який шар збрехав: додаток, проксі, кеш або конфігурація. Найшвидший шлях — докази, а не відчуття: захопіть заголовки, порівняйте edge vs origin, інспектуйте перенаправлення і підтвердіть канонічну схему/хост.
Зробіть це далі, у порядку:
- Запустіть перевірку заголовків на
/wp-login.phpі підтвердьтеSet-Cookieі відсутність публічного кешування. - Слідкуйте ланцюжок перенаправлень для
/wp-admin/і усуньте змішані хости/схеми. - Обійдіть edge і порівняйте. Якщо origin працює — виправляйте правила edge (кеш і обробку заголовків).
- Якщо бачите «headers already sent» — відключіть проблемний плагін і вважайте це дефектом коду, а не конфігураційною особливістю.
- Додайте невелику синтетичну перевірку, щоб ви ніколи не дізналися про цю проблему від розлюченого керівника.