isso será longo ...
Tenho um caso grave de falha de logon incorreta, devido ao gerenciamento incorreto de cookies. Antes de tudo, estou gerenciando uma loja fechada (B2B) na qual os clientes precisam fazer login antes de poderem ver o catálogo. Todo acesso não registrado é redirecionado para a página de login, mas de vez em quando o cliente não pode fazer login, mesmo que o nome de usuário e a senha estejam corretos. Digo 'nome de usuário' porque uso a extensão Diglin_Username e o plug-in StoreRestricition para obter o comportamento desejado. O que acontece é que, às vezes, encontrei dois conjuntos diferentes de cookies deixados pelo Magento, e eles se referem a dois domínios diferentes (.abc.com e .abc.com, por exemplo).
Depois de ler este artigo do grande Alan Storm sobre a instanciação da sessão inicial e de encontrar o temido cookie PHPSESSID no meu navegador, investiguei com profundidade o problema.
O que eu encontrei é de duas caras. Primeiro, coloquei uma chamada Mage :: Log () na função start () na classe Mage_Core_Model_Session_Abstract_Varien para registrar as várias tentativas feitas pelo Magento para iniciar uma nova sessão e notei que, após a primeira chamada Mage :: run (), invoque o preDispatch () Os métodos, dispatch () e postDispatch () da classe Mage_Core_Controller_Front_Action são chamados na sequência usual, mas parece que quando o postDispatch () é executado, ele não consegue encontrar a sessão iniciada por preDispatch () e continua a criar uma nova sessão. A esse respeito, encontrei uma diferença no código entre as versões Magento 1.7.xe 1.8.x e acho que talvez possa resolver o problema:
Magento 1.7.x - classe Mage_Core_Model_Session_Abstract_Varien:
public function start($sessionName=null)
{
if (isset($_SESSION)) {
return $this;
}
.
.
}
Magento 1.8.x - classe Mage_Core_Model_Session_Abstract_Varien:
public function start($sessionName=null)
{
if (isset($_SESSION) && !$this->getSkipEmptySessionCheck()) {
return $this;
}
.
.
}
Porém, não consigo encontrar onde definir a propriedade SkipEmptySessionCheck, então acabei corrigindo a classe Mage_Core_Controller_Front_Action desta maneira:
public function postDispatch()
{
parent::postDispatch();
if (!$this->getFlag('', self::FLAG_NO_START_SESSION )) {
if (session_id()) {
Mage::getSingleton('core/session')->setLastUrl(Mage::getUrl('*/*/*', array('_current'=>true)));
}
}
return $this;
}
ter postDispatch () não chamando Mage :: getSingleton ('core / session') (que teria criado uma nova sessão) se não conseguir encontrar uma sessão já iniciada. Tanto tempo para o cookie PHPSESSID e pronto, pensei ...
Mas não é assim. Agora, me livrei do cookie PHPSESSID, mas ainda assim pego dois conjuntos diferentes de cookies (erraticamente) salvos no navegador. Excluindo apenas os cookies errados, consigo entrar com êxito ou sou redirecionado para a página de login sem nem mesmo uma mensagem. Tentei indicar o domínio do cookie explicitamente na configuração do sistema, mas isso não resolveu o problema.
Profundamente na base de código novamente, e descobri que nos vários locais em que o Magento define um cookie, é necessário o domínio para usar a partir da função getDomain () na classe Mage_Core_Model_Cookie:
public function getDomain()
{
$domain = $this->getConfigDomain();
if (empty($domain)) {
$domain = $this->_getRequest()->getHttpHost();
}
return $domain;
}
Agora, se você olhar para a página do Magento no seu navegador, poderá encontrar na seção 'cabeça' algo como isto:
<script type="text/javascript">
//<![CDATA[
Mage.Cookies.path = '/';
Mage.Cookies.domain = '.www.abc.com';
//]]>
</script>
Essas linhas vêm de app / design / frontend / base / default / template / page / js / cookie.phtml:
<script type="text/javascript">
//<![CDATA[
Mage.Cookies.path = '<?php echo $this->getPath()?>';
Mage.Cookies.domain = '<?php echo $this->getDomain()?>';
//]]>
</script>
e, por sua vez, esse código faz referência à função getDomain () na classe Mage_Page_Block_Js_Cookie:
public function getDomain()
{
$domain = $this->getCookie()->getDomain();
if (!empty($domain[0]) && ($domain[0] !== '.')) {
$domain = '.'.$domain;
}
return $domain;
}
Portanto, se eu definir o domínio do cookie na configuração do sistema como, por exemplo, 'www.abc.com', terminarei com:
Mage.Cookies.domain = '.www.abc.com'
e encontrando no meu navegador os cookies 'www.abc.com' e '.www.abc.com', pensei: "ok, configurarei '.abc.com' na configuração do sistema e sempre terminará com ' .abc.com 'cookies !! "...
Mas de jeito nenhum. Agora, na minha página HTML, sempre recebo '.abc.com', mas mesmo assim ainda recebo erraticamente um cookie 'www.abc.com' e nenhum login.
Estou perplexo, e meu cliente está começando a pensar que não sou tão bom quanto ele pensava que eu era (estou começando a pensar isso também ...) :(
Alguns de vocês (e moças) têm alguma dica?
ATUALIZAÇÃO: Eu vi alguém relacionando problemas com sessões e cookies ao uso do Varnish como cache do Magento. Como também estou usando o Varnish, tentarei desabilitá-lo. O problema pode ser resolvido.
Respostas:
Este é um artigo da NovusWeb: http://www.novusweb.com/fix-for-passing-magento-session-ids/
Correção para passar IDs de sessão Magento
Autor: Brett Williams
Postado 9 de novembro de 2011
Corrigindo IDs de Sessão Magento
Geralmente, usamos SSLs compartilhados na criação de sites de comércio eletrônico. É uma maneira conveniente de hospedar várias lojas sem precisar comprar certificados SSL separados para cada site. A maioria dos nossos clientes de comércio eletrônico gerencia várias lojas em uma única instalação Magento ou OpenCart. Recentemente, descobrimos um problema no Magento em que o ID da sessão do cliente não estava sendo passado com êxito entre a visita inicial ao site e as visualizações de página após o logon na loja como um cliente registrado. O Magento não passava os mesmos IDs de sessão, e isso significava que um cliente que já havia feito login e adicionado itens ao carrinho, perderia o conteúdo do carrinho depois de retornar mais tarde e efetuar login. Não é uma situação ótima.
Ao examinar os cookies criados durante uma sessão, descobri que, ao passar de um domínio não seguro (por exemplo, http: //) para um domínio seguro (por exemplo, https: //), o ID da sessão estava sendo passado com êxito e um novo o cookie para o domínio seguro foi criado com o mesmo ID de sessão que o domínio não seguro. No entanto, quando o cliente efetuou login, um novo cookie foi criado para o domínio seguro com um ID de sessão totalmente novo. Agora, o Magento estava usando o cookie mais recente e, sempre que o cliente clicava para voltar para uma página de domínio não segura (por exemplo, página de detalhes do produto), não era mais possível acessar o Magento porque o domínio não seguro estava usando seu ID de cookie / sessão, não o novo ID da sessão criado no login. A solução seria descobrir onde o novo ID da sessão estava sendo criado e impedir que isso ocorresse.
Então, comecei a pesquisar no código para ver se encontrava onde o Magento estava criando a nova sessão.
Em app / code / core / Mage / Customer / Model / session.php, encontrei isso nas linhas 177-189 (Magento CE 1.5.1):
Minha solução foi comentar a linha: $ this-> renewSession () :, para que o Magento não crie uma nova sessão quando o cliente estiver logado. O código alterado fica assim:
Até o momento em nossos testes, tudo está funcionando bem, e a sessão do cliente está sendo mantida entre domínios. Agora, antes de se apressar para alterar este arquivo principal, faça o seguinte:
Faça backup dos seus bancos de dados (você sempre deve fazer isso antes de fazer qualquer modificação). Crie a seguinte hierarquia de diretórios: app / code / local / Mage / Customer / Model /. Coloque uma cópia do session.php nesse novo diretório. Comente a linha apropriada, mostrada acima, e salve seu arquivo. Ao colocar suas modificações no diretório app / code / local, você está dizendo ao Magento para usar esses arquivos em vez dos arquivos principais. Mais importante, você está impedindo a perda de suas modificações caso atualize o Magento no futuro.
Ele também fornece uma maneira conveniente de armazenar e gerenciar suas modificações de código, pois você só precisa manter os arquivos modificados no diretório app / code / local.
Deixe um comentário se souber de uma solução mais elegante ou se achar que isso funciona ou não.
fonte
app/code/local/Mage/*
. Antes da atualização do Magento, extraia o código do instalador e compare com o código modificado para ver se é diferente. Nesse caso, modifique a nova versão a ser implementada após a atualização. Nada como preservá-lo na atualização para que o site caia devido a alterações incompatíveis no conteúdo.$this->renewSession();
para asetCustomerAsLoggedIn()
função.code/core/Mage/Core/Model/Session/Abstract.php
ecode/core/Mage/Admin/Model/Session.php
onde pode ser comentada. Em uma cópia local do modelo, é claro. @FiascoLabs melhor ainda, realizar uma substituição adequada de apenas a função, é necessário modificar, e deixar o resto do arquivo intactos no núcleo :)