Я виявляю, що кожного разу, коли перезапускаю Varnish на своєму сервері, я втрачаю свої сеанси для своїх користувачів.
Це черга змушує моїх клієнтів втрачати свої кошики.
Це нормальна поведінка для Varnish чи я винен у моєму VCL? Здавалося б, її немає
Додаткова інформація.
При подальшому розслідуванні виявляється, що ця проблема пов'язана з випуском № 725 на GitHub.
Моя установка Magento - версія 1.9.1.0. Слід сказати також, що весь мій фронтенд ведеться під https. Я використовую фунт перед лаком для припинення SSL.
Здається, що поведінка Magento за замовчуванням у цій версії полягає у створенні вторинного файлу cookie, який зазвичай називається "frontend_cid", у спробі протестувати проти атак MITM.
Схоже, що створений Turpentine файл VCL не передає цей файл cookie, що спричиняє недійсні сеанси.
Чи може хтось пояснити, як файл VCL передає файли cookie, які Magento надає Клієнту?
Я звузив це до лаку, не генеруючи необхідні файли cookie.
Станом на Magento 1.9.1.0 було введено cookie 'frontend_cid' для блокування MITM-атак.
Це можна знайти в Mage_Core_Model_Session_Abstract_Varien
класі, у рядку 135
if (Mage::app()->getFrontController()->getRequest()->isSecure() && empty($cookieParams['secure'])) {
// secure cookie check to prevent MITM attack
$secureCookieName = $sessionName . '_cid';
if (isset($_SESSION[self::SECURE_COOKIE_CHECK_KEY])
&& $_SESSION[self::SECURE_COOKIE_CHECK_KEY] !== md5($cookie->get($secureCookieName))
) {
session_regenerate_id(false);
$sessionHosts = $this->getSessionHosts();
$currentCookieDomain = $cookie->getDomain();
foreach (array_keys($sessionHosts) as $host) {
// Delete cookies with the same name for parent domains
if (strpos($currentCookieDomain, $host) > 0) {
$cookie->delete($this->getSessionName(), null, $host);
}
}
$_SESSION = array();
}
if (!isset($_SESSION[self::SECURE_COOKIE_CHECK_KEY])) {
$checkId = Mage::helper('core')->getRandomString(16);
$cookie->set($secureCookieName, $checkId, null, null, null, true);
$_SESSION[self::SECURE_COOKIE_CHECK_KEY] = md5($checkId);
}
}
Щоб забезпечити безпечне з'єднання для клієнтів, Varnish повинен створити певний файл "frontend", який Magento пізніше використовуватиме для ідентифікації конкретного клієнта. Поки, здається, це робиться просто чудово. Однак, схоже на Magento 1.9.1.0, тепер йому також потрібно генерувати файли cookie 'frontend_cid'.
Лак повинен це зробити, тому що, кешуючи відповідь, він також кешує заголовок відповіді, який містить файли cookie 'frontend'.
Таким чином, за замовчуванням Varnish видаляє будь-які файли cookie, з якими сервер відповідає, коли обробляє умови "пошуку" або "проходу". Це робиться для того, щоб зупинити отримання декількох користувачів одним і тим самим кешованим файлом cookie для фронтену (що може скомпрометувати сеанси людей).
У будь-який час, коли лак обробляє запит "pipe", Magento може створити необхідні файли cookie та приєднати їх до браузера користувачів. Це призводить до відмови системи в початковій валідації, а потім надання нового сеансу для користувача. Цей симптом проявляється втратою кошика або неможливістю додати товари до кошика.
Терпентиновий VCL буде "передавати" будь-який запит, який НЕ є типу методу GET або HEAD, як це бачить цей код у vcl_recv
функції:
// We only deal with GET and HEAD by default
// we test this here instead of inside the url base regex section
// so we can disable caching for the entire site if needed
if (!true || req.http.Authorization ||
req.request !~ "^(GET|HEAD)$" ||
req.http.Cookie ~ "varnish_bypass=1") {
return (pipe);
}
Тому симптом є найбільш помітним, коли користувач намагається додати товар у свій кошик або намагається оформити замовлення вперше.
Як виправити?
Я вважаю, що вирішення цього питання полягає в тому, щоб Turpentine VCL також створив cookie 'frontend_cid' для вхідних відвідувачів, а потім модуль скипидару додасть цей cookie до поточного сеансу, як це робиться зараз для файлу cookie 'frontend'.
Отже ... як ми це реалізуємо?
Caveat: Я можу помилитися, я дуже новачок в лаку, але я витратив на це багато годин, і це те, що я бачу, будь-хто, хто зараз підтримує, був би дуже вдячний.
Фінальне оновлення та мій вибір виправлення - 2015 10 30
Неможливо створити печиво 'frontend_cid' у лаці, оскільки файл cookie створюється навмання на сервері Magento та зберігається як хеш MD5 у сеансі з клієнтами. Це не дозволяє вам створювати зовні за межами сесії клієнтів.
Найкраще рішення, яке я придумав у цьому питанні, - замість того, щоб замінити спосіб, яким Magento обробляє сеанси клієнтів.
В даний час Magento обробляє недійсні сеанси, як це:
IF
The requested session by the customer is flagged as invalid
THEN
Stop processing request
Redirect to the appropriate page
Моя нова логіка полягає в наступному:
IF
The requested session by the customer is flagged as invalid
THEN
Create a new session
Complete the requested task
Redirect to the appropriate page
Мій новий підхід дозволяє лакованому керувати відгуками клієнтів навіть у перший візит. Це не так, як працює остання реалізація скипидару.
Мій випуск, випуск № 829 - / nexcess / magento-скипидар / випуски / 829 на GitHub. Копію мого VCL можна знайти тут.
Моя проблема в GitHub закрита, оскільки це дублікат значно старшої проблеми, знайденої тут: