Verniz e aguarrás

9

Estou descobrindo que, sempre que reinicio o Varnish no meu servidor, estou perdendo minhas sessões para meus usuários.

É a vez de fazer meus clientes perderem seus carrinhos de compras.

Esse comportamento é normal para o verniz ou o meu VCL é o culpado? Parece que não é


Mais informações.

Em uma investigação mais aprofundada, parece que esse problema está relacionado ao problema nº 725 no GitHub.

Minha instalação do Magento é a versão 1.9.1.0. Também deve ser dito que todo o meu front-end está sendo executado em https. Estou usando Libra na frente do Varnish para finalizar o SSL.

Parece que o comportamento padrão do Magento nesta versão é criar um cookie secundário de front-end, geralmente chamado de 'frontend_cid'. Na tentativa de testar contra ataques MITM.

Parece que o arquivo VCL gerado pelo Turpentine não está transmitindo esse cookie, o que está causando sessões inválidas.

Alguém pode explicar como o arquivo VCL passa os cookies que o Magento cria para o cliente?


Eu reduzi isso para o Varnish, não gerando os cookies necessários.

A partir do Magento 1.9.1.0, um cookie 'frontend_cid' foi introduzido para bloquear ataques MITM.

Isso pode ser encontrado na Mage_Core_Model_Session_Abstract_Varienclasse, na linha 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 fornecer conexões seguras para os clientes, o Varnish precisa gerar um cookie 'frontend', que o Magento mais tarde usará para identificar esse cliente em particular. Até agora, parece fazer isso muito bem. No entanto, parece que a partir do Magento 1.9.1.0, agora ele também precisa gerar o cookie 'frontend_cid'.

O Varnish precisa fazer isso porque, ao armazenar em cache a resposta, ele também armazena em cache o cabeçalho da resposta, que contém os cookies 'frontend'.

Portanto, por padrão, o Varnish descarta todos os cookies com os quais o back-end responde quando ele manipula as condições de 'consulta' ou 'aprovação'. Isso é feito para impedir que vários usuários sejam emitidos com o mesmo cookie de front-end em cache (que comprometeria as sessões das pessoas).

Sempre que o verniz lida com a solicitação com 'pipe', o Magento pode criar os cookies necessários e anexá-los ao navegador do usuário. Isso resulta no sistema falhando na validação inicial, mas fornecendo uma nova sessão ao usuário. Esse sintoma se manifesta como uma perda de carrinho ou a incapacidade de adicionar produtos ao carrinho de compras.

O Turpentine VCL 'encaminhará' qualquer solicitação que NÃO seja do tipo GET ou HEAD do método, como visto por este código na vcl_recvfunção:

// 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);
}

Portanto, o sintoma é mais perceptível quando o usuário tenta adicionar um item ao carrinho ou tenta fazer o checkout pela primeira vez.


Como consertar?

Acredito que a solução para esse problema é fazer com que o Turpentine VCL também crie um cookie 'frontend_cid' para os visitantes recebidos e, em seguida, faça com que o módulo turpentine adicione esse cookie à sessão atual, como agora faz com o cookie 'frontend'.

Então ... como implementamos isso?

Advertência: Eu posso estar errado, sou muito novo no Varnish, mas passei muitas horas nisso agora e é isso que estou vendo, qualquer pessoa que esteja apoiando agora seria muito apreciada.

ATUALIZAÇÃO FINAL E MINHA CORREÇÃO ESCOLHIDA - 2015 10 30

É impossível criar um cookie 'frontend_cid' em verniz, pois o cookie é criado aleatoriamente no servidor pelo Magento e armazenado como um hash MD5 na sessão de clientes. Isso impede que você crie externamente fora da sessão do cliente.

A melhor solução que encontrei nessa questão é substituir a maneira como o Magento lida com as sessões dos clientes.

Atualmente, o Magento lida com sessões inválidas como esta:

IF
    The requested session by the customer is flagged as invalid
THEN
    Stop processing request
    Redirect to the appropriate page

Minha nova lógica é a seguinte:

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

Minha nova abordagem permite envernizada para lidar com a resposta dos clientes mesmo na primeira visita. Não é assim que funciona a mais recente implementação de terebintina.


Minha Edição, Edição 829 - / nexcess / magento-aguarrás / edições / 829 no GitHub. Uma cópia da minha VCL pode ser encontrada aqui.


Meu problema no GitHub foi encerrado, pois é uma duplicata de um problema muito mais antigo encontrado aqui:

Edição 345

Peter A
fonte
11
Vi que você acabou de abrir um problema no GitHub, vou ver amanhã de manhã. Enquanto isso, você pode verificar github.com/nexcess/magento-turpentine/issues/90 e github.com/nexcess/magento-turpentine/issues/92 .
mbalparda
isso é impossível, as sessões são armazenadas no magento e no navegador dos usuários, o verniz não tem nada a ver com isso. algo provavelmente está configurado errado.

Respostas:

4

Isso pode ser causado pela configuração incorreta do caminho do cookie.

Tente definir as configurações de cookies, Admin->Configuration->Web->Session Cookie Managementse ainda não estiver.

Alternativamente, pode ser um bug no verniz.

performadigital
fonte
Obrigado @performadigital, fiz uma investigação mais aprofundada e estou atualizando minha pergunta.
Peter A
1

Suspeito que seu problema foi resolvido por uma atualização recente do Turpentine: https://github.com/nexcess/magento-turpentine/commit/66615b7cc987854e8671911ab6c3aa22afb808a2

Geração de sessão removida Corrige os problemas # 806, # 345 e muitos outros relacionados a sessões extras, carrinhos vazios, etc.

Faz com que o verniz seja ignorado no carregamento da primeira página para novas sessões.

Portanto, o Varnish não precisa mais tentar falsificar o cookie da sessão (ao custo de não poder responder do cache à solicitação da primeira página)

Descobrimos que essa alteração resolveu esse problema para vários de nossos clientes Magento ( rodamos www.section.io ).

mattnthat
fonte
11
Obrigado @mattnthat, estou ciente da solução proposta, mas não a considero aceitável. Acabei implementando uma solução diferente. Fiz o Magento verificar se a sessão era válida e, se não, em vez de encerrar o script, fiz inicializar uma nova sessão e concluir a solicitação.
Peter A