Estoy descubriendo que cada vez que reinicio Varnish en mi servidor, pierdo mis sesiones para mis usuarios.
Este es el turno de hacer que mis clientes pierdan sus carritos de compras.
¿Es este comportamiento normal para Varnish o es mi culpa VCL? Parece que no es
Informacion adicional.
En una investigación adicional, parece que este problema está relacionado con el Problema # 725 en GitHub.
Mi instalación de Magento es la versión 1.9.1.0. También se debe decir que toda mi interfaz se ejecuta bajo https. Estoy usando Pound delante de Varnish para terminar SSL.
Parece que el comportamiento predeterminado de Magento en esta versión es crear una cookie de interfaz secundaria, típicamente llamada 'frontend_cid', en un intento de probar contra ataques MITM.
Parece que el archivo VCL generado por Turpentine no está transmitiendo esta cookie, lo que está causando sesiones no válidas.
¿Alguien puede explicar cómo el archivo VCL pasa las cookies que Magento hace al Cliente?
Lo he reducido a Varnish que no genera las cookies requeridas.
A partir de Magento 1.9.1.0, se introdujo una cookie 'frontend_cid' para bloquear los ataques MITM.
Esto se puede encontrar en la Mage_Core_Model_Session_Abstract_Varien
clase, en la línea 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);
}
}
Para proporcionar conexiones seguras a los clientes, Varnish tiene que generar una cookie 'frontend', que Magento usará más tarde para identificar a ese cliente en particular. Hasta ahora, parece hacer esto bien. Sin embargo, parece que a partir de Magento 1.9.1.0, ahora también necesita generar la cookie 'frontend_cid'.
Varnish tiene que hacer esto porque, al almacenar en caché la respuesta, también almacena en caché el encabezado de respuesta, que contiene las cookies 'frontend'.
Por lo tanto, de forma predeterminada, Varnish elimina las cookies con las que el backend responde cuando maneja las condiciones de 'búsqueda' o 'aprobación'. Hace esto para evitar que se emitan varios usuarios con la misma cookie de interfaz en caché (que comprometería las sesiones de las personas).
Cada vez que barniz maneja la solicitud con 'pipe', Magento puede crear las cookies necesarias y adjuntarlas al navegador del usuario. Esto da como resultado que el sistema falle la validación inicial, pero luego proporcione una nueva sesión al usuario. Este síntoma se manifiesta como una pérdida del carrito o la incapacidad de agregar productos al carrito de compras.
El VCL de trementina 'canalizará' cualquier solicitud que NO sea del tipo de método GET o HEAD como se ve en este código en la vcl_recv
función:
// 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);
}
Por lo tanto, el síntoma es más notable cuando el usuario intenta agregar un artículo a su carrito o intenta realizar el pago por primera vez.
¿Como arreglar?
Creo que la solución a este problema es hacer que Turpentine VCL también cree una cookie 'frontend_cid' para los visitantes entrantes, y luego haga que el módulo de trementina agregue esa cookie a la sesión actual como lo hace ahora para la cookie 'frontend'.
Entonces ... ¿cómo implementamos esto?
Advertencia: podría estar equivocado, soy muy nuevo en Varnish, pero he pasado muchas horas en esto ahora y esto es lo que estoy viendo, cualquier persona que esté apoyando en este momento sería muy apreciada.
ACTUALIZACIÓN FINAL Y MI REVISIÓN ELEGIDA - 2015 10 30
Es imposible crear una cookie 'frontend_cid' en barniz ya que Magento crea la cookie al azar en el servidor y la almacena como un hash MD5 en la sesión de los clientes. Esto le impide crear en forma externa fuera de la sesión de clientes.
La mejor solución que se me ocurrió en este tema es sobrescribir la forma en que Magento maneja las sesiones de los clientes.
Actualmente Magento maneja sesiones inválidas como esta:
IF
The requested session by the customer is flagged as invalid
THEN
Stop processing request
Redirect to the appropriate page
Mi nueva lógica es la siguiente:
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
Mi nuevo enfoque permite barnizar para manejar la respuesta de los clientes incluso en la primera visita. Que no es así como funciona la última implementación de trementina.
My Issue, Issue # 829 - / nexcess / magento-trepentine / issues / 829 en GitHub. Una copia de mi VCL se puede encontrar aquí.
Mi problema en GitHub se ha cerrado ya que es un duplicado de un problema mucho más antiguo que se encuentra aquí: