我发现,每当在服务器上重新启动Varnish时,我就会为用户失去会话。
这是轮到我的顾客放弃购物车了。
这是Varnish的正常行为,还是应该归咎于我的VCL?似乎不是
进一步的信息。
经过进一步调查,似乎此问题与GitHub上的Issue#725有关。
我的Magento安装版本为1.9.1.0。还应该说我的整个前端都在https下运行。我在Varnish前面使用Pound终止SSL。
在此版本中,Magento的默认行为似乎是创建辅助前端cookie,通常称为“ frontend_cid”,以尝试抵御MITM攻击。
看起来Turpentine生成的VCL文件没有传递此cookie,这导致了无效的会话。
谁能解释VCL文件如何将Magento传递给客户端的Cookie传递给他人?
我将范围缩小到Varnish,不生成所需的cookie。
从Magento 1.9.1.0开始,引入了一个“ frontend_cid” cookie来阻止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必须生成一个“前端” cookie,Magento稍后将使用该cookie来识别该特定客户。到目前为止,似乎可以做到这一点。但是,从Magento 1.9.1.0开始,它现在还需要生成“ frontend_cid” cookie。
Varnish必须这样做,因为通过缓存响应,它还缓存了包含“前端” cookie的响应标头。
因此,默认情况下,Varnish会抛弃后端在处理“查找”或“通过”条件时响应的所有cookie。这样做是为了阻止向多个用户发出相同的缓存的前端cookie(这会危害人员会话)。
每当清漆使用“管道”处理请求时,Magento就能创建所需的cookie并将其附加到用户浏览器。这导致系统无法通过初始验证,但随后向用户提供了新会话。此症状表现为购物车丢失或无法向购物车添加产品。
Turpentine 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也为传入的访问者创建一个'frontend_cid'cookie,然后像现在对'frontend'cookie一样,将turpentine模块将该cookie添加到当前会话中。
那么... 我们如何实现呢?
警告:我可能是错的,我对Varnish还是很陌生,但是我现在已经花了很多时间在此上,这就是我所看到的,现在任何人的支持将不胜感激。
最后更新和我选择的修复-2015 10 30
无法使用清漆创建“ frontend_cid” cookie,因为该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期-GitHub上的/ nexcess / magento-turpentine / issues / 829。我的VCL副本可在此处找到。
我在GitHub上的问题已经关闭,因为它是在这里发现的一个更老的问题的重复: