ce sera long ...
J'ai un mauvais cas d'échec de connexion erratique, en raison d'une mauvaise gestion des cookies. Tout d'abord, je gère un magasin fermé (B2B) dans lequel les clients doivent se connecter avant de pouvoir voir le catalogue. Chaque accès non enregistré est redirigé vers la page de connexion, mais de temps en temps le client ne peut pas se connecter même si le nom d'utilisateur et le mot de passe sont corrects. Je dis «nom d'utilisateur» car j'utilise l'extension Diglin_Username et le plugin StoreRestricition pour obtenir le comportement souhaité. Ce qui se passe, c'est que parfois j'ai trouvé deux ensembles de cookies différents laissés par Magento, et ils se réfèrent à deux domaines différents (.www.abc.com et .abc.com par exemple).
Après avoir lu cet article du grand Alan Storm sur l'instanciation de la première session et trouvé le redoutable cookie PHPSESSID dans mon navigateur, j'ai étudié en profondeur le problème.
Ce que j'ai trouvé est à double face. J'ai d'abord mis un appel Mage :: Log () dans la fonction start () de la classe Mage_Core_Model_Session_Abstract_Varien pour enregistrer les différentes tentatives faites par Magento pour démarrer une nouvelle session et j'ai remarqué qu'à la suite de la première invocation de Mage :: run (), le preDispatch () , les méthodes dispatch () et postDispatch () de la classe Mage_Core_Controller_Front_Action sont appelées dans la séquence habituelle mais il semble que lorsque postDispatch () s'exécute, il ne trouve pas la session démarrée par preDispatch () et procède à la création d'une nouvelle session. À cet égard, j'ai trouvé une différence dans le code entre les versions Magento 1.7.x et 1.8.x et je pense que cela pourrait peut-être résoudre le problème:
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;
}
.
.
}
Je ne peux tout simplement pas trouver où définir la propriété SkipEmptySessionCheck, alors j'ai fini par patcher la classe Mage_Core_Controller_Front_Action de cette manière:
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;
}
pour que postDispatch () n'appelle pas Mage :: getSingleton ('core / session') (qui aurait créé une nouvelle session) s'il ne trouve pas une session déjà démarrée. Tant de temps pour le cookie PHPSESSID et tout est fait, je pensais ...
Mais non. Maintenant, je me suis débarrassé du cookie PHPSESSID mais j'ai toujours deux ensembles de cookies différents (de manière erratique) enregistrés dans le navigateur. En supprimant uniquement les mauvais cookies, je peux me connecter avec succès, ou je suis redirigé vers la page de connexion sans même un message. J'ai essayé d'indiquer explicitement le domaine des cookies dans la configuration du système, mais cela n'a pas résolu le problème.
Profondément dans la base de code, et j'ai trouvé que dans les différents endroits où Magento définit un cookie, il prend le domaine à utiliser à partir de la fonction getDomain () dans la classe Mage_Core_Model_Cookie:
public function getDomain()
{
$domain = $this->getConfigDomain();
if (empty($domain)) {
$domain = $this->_getRequest()->getHttpHost();
}
return $domain;
}
Maintenant, si vous regardez la page que vous obtenez de Magento dans votre navigateur, vous pouvez trouver dans la section «tête» quelque chose comme ceci:
<script type="text/javascript">
//<![CDATA[
Mage.Cookies.path = '/';
Mage.Cookies.domain = '.www.abc.com';
//]]>
</script>
Ces lignes proviennent 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>
et à son tour, ce code fait référence à la fonction getDomain () dans la classe Mage_Page_Block_Js_Cookie:
public function getDomain()
{
$domain = $this->getCookie()->getDomain();
if (!empty($domain[0]) && ($domain[0] !== '.')) {
$domain = '.'.$domain;
}
return $domain;
}
Donc, si je définit le domaine des cookies dans la configuration système comme, par exemple, «www.abc.com», je me retrouve avec:
Mage.Cookies.domain = '.www.abc.com'
et en trouvant dans mon navigateur les cookies "www.abc.com" et ".www.abc.com", je me suis dit "ok, je vais mettre" .abc.com "dans la configuration du système et je finirai toujours par" Cookies .abc.com !! "...
Mais pas question. Maintenant, dans ma page HTML, je reçois toujours «.abc.com» mais néanmoins j'ai toujours un cookie «www.abc.com» et aucune connexion.
Je suis perplexe, et mon client commence à penser que je ne suis pas aussi bon qu'il le pensait (je commence à penser cela aussi ...) :(
Certains d'entre vous (et filles) ont-ils un indice?
MISE À JOUR: J'ai vu quelqu'un relier des problèmes de sessions et de cookies à l'utilisation de Varnish comme cache pour Magento. Comme j'utilise aussi Varnish, je vais essayer de le désactiver si le problème peut être résolu.