Статьи

Как исправить проблемы входа в Magento с помощью файлов cookie и сессий

Эта статья была создана в сотрудничестве с Ktree . Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.

В этой статье мы рассмотрим, как файлы cookie Magento могут создавать проблемы с функциональностью входа в систему как клиентского, так и административного интерфейса, причину, по которой это происходит, и способы ее устранения.

Это также называется проблемой зацикливания, поскольку экран перенаправляется на тот же экран, даже если имя пользователя и пароль верны.

В конце статьи приведен сценарий, который может помочь выявить некоторые проблемы. Не стесняйтесь использовать и изменять в соответствии с вашими потребностями.

Что такое печенье?

Файл cookie — это фрагмент текста, который веб-сервер может хранить на жестком диске пользователя, а затем может впоследствии извлечь его. Magento использует файлы cookie в функциях Cart & Backend Admin, и они могут стать источником нескольких проблем при невозможности входа в Magento.

Что такое сессия?

Сеанс — это переменная массива на стороне сервера, которая хранит информацию, которая будет использоваться на нескольких страницах. Например, элементы, добавленные в корзину, обычно сохраняются в сеансах, а когда пользователь просматривает страницу оформления заказа, они считываются из сеанса.

Сессии идентифицируются по уникальному идентификатору. Его имя меняется в зависимости от языка программирования — в PHP это называется «PHP Session ID». Как вы уже догадались, тот же ID Session ID должен быть сохранен в виде куки в клиентском браузере для связи.

Хранилище сессий Magento

Magento может хранить сеансы через нескольких поставщиков сеансов, и это можно настроить в файле конфигурации Magento по адресу app/etc/local.xml . Эти поставщики сеансов могут быть выбраны здесь.

файл

 <session_save><![CDATA[files]]></session_save> <session_save_path> <![CDATA[/tmp/session]]> </session_save_path> 

База данных

Разрешение сеансов сохранять себя в базе данных выполняется в /app/etc/local.xml путем добавления <session_save><![CDATA[db]]></session_save> .

Приложения Magento хранят сеансы в таблице Core\_session .

Redis

 <session_save>db</session_save> <redis_session> <host>127.0.0.1</host> <port>6379</port> </redis_session> 

MemCache

 session_save><![CDATA[memcache]]></session_save> <session_save_path> <![CDATA[tcp://localhost:11211?persistent=1&weight=2&timeout=10&retry_interval=10]]> </session_save_path> 

Использование Magento

Magento использует два разных файла cookie с именами «frontend» и «adminhtml». Первая создается при просмотре любой страницы. Этот файл cookie также обновляется всякий раз, когда клиент входит в систему, а следующий создается при входе внутреннего пользователя. Вы можете проверить, были ли созданы файлы cookie, нажав Inspect Element> Application , как показано на рисунке ниже (из Chrome ):

Файлы cookie настраиваются в Magento через меню администратора «Конфигурация» — « Система»> «Конфигурация»> «Общие»> «Интернет» .

Проблема: Ошибка входа и перенаправления на страницу входа

Если вы не сталкивались с этой проблемой, значит, вы недостаточно долго работали с Magento!

Обычно так и происходит: когда вы входите в систему, вводя свое имя пользователя и пароль, вы будете перенаправлены на ту же страницу входа и URL, а ваш браузер будет добавлен с nonce id. Это происходит как для клиентского интерфейса, так и для фонового входа Magento.

Давайте рассмотрим несколько причин, почему это происходит, и как мы должны решить эти проблемы.

Причина № 1: Домен cookie не соответствует домену сервера

Допустим, ваш Magento-сайт — example.com а домен cookie в Magento настроен как xyz.com .

В этом сценарии оба куки-файла Magento установят Domain Value как xyz.com , но для проверки сеанса Magento рассмотрит домен, через который был осуществлен доступ к сайту — в данном случае example.com . Поскольку он не сможет найти активный сеанс со значением домена example.com , он перенаправит пользователя на страницу входа в систему, даже если предоставлены действительные учетные данные.

app/code/core/Mage/Core/Model/Session/Abstract.php

После входа в систему или выхода из системы система Magento сгенерирует сессию, используя следующий скрипт:

 public function renewSession() { $this->getCookie()->delete($this->getSessionName()); $this->regenerateSessionId(); $sessionHosts = $this->getSessionHosts(); $currentCookieDomain = $this->getCookie()->getDomain(); if (is_array($sessionHosts)) { foreach (array_keys($sessionHosts) as $host) { // Delete cookies with the same name for parent domains if (strpos($currentCookieDomain, $host) > 0) { $this->getCookie()->delete($this->getSessionName(), null, $host); } } } return $this; } 

app/code/core/Mage/Core/Model/Session/Abstract/Varien.php

Magento проверит сессию для каждого запроса следующим способом:

 public function init($namespace, $sessionName=null) { if (!isset($_SESSION)) { $this->start($sessionName); } if (!isset($_SESSION[$namespace])) { $_SESSION[$namespace] = array(); } $this->_data = &$_SESSION[$namespace]; $this->validate(); $this->revalidateCookie(); return $this; } 

Обычно вы можете видеть это, когда вы переносите свой экземпляр Magento из одного домена в другой домен, например из производства в промежуточный, и забыли изменить домен cookie.

Примечание: вы можете запустить предоставленный скрипт cookieTest.php , который проверяет, что является доменным файлом cookie сервера и что установлено в конфигурации Magento.

Решение:

Измените Cookie-домен через меню администратора конфигурации. Перейдите в System> Configuration> General> Web , как показано на скриншоте.

В качестве альтернативы вы можете изменить это, запустив эти SQL-запросы.

Для проверки домена cookie используйте этот запрос select для получения конфигурации:

 SELECT * FROM core_config_data WHERE path = 'web/cookie/cookie_domain'; 

После выполнения этого запроса мы получим результаты. Убедитесь, что столбец ‘value’ совпадает с вашим доменом. Обновите значение, если оно не совпадает с вашим доменом.

Чтобы обновить домен cookie, используйте этот запрос:

 UPDATE core_config_data SET VALUE = "domain.com" WHERE path = 'web/cookie/cookie_domain'; 

Причина № 2: используется несколько поддоменов, и неверная конфигурация файлов cookie в Magento

Допустим, ваш сайт — example.com . Вход в example.com/admin работает нормально.

Но на вашем промежуточном / QA-сайте, например staging.example.com/admin , вы не можете войти без удаления всех файлов cookie. Система может разрешить вход в систему на staging.example.com , но когда мы снова staging.example.com сайт example.com/admin , ваш следующий щелчок на staging.example.com вас на страницу входа. Аналогичное поведение наблюдается и для клиентов, использующих интерфейсный вход в систему.

Решение 1

Вариант A: если ваш основной домен и субдомены размещены на одном сервере

  • Измените Cookie-домен через меню администратора конфигурации. Перейдите в System> Configuration> General> Web , как показано на скриншоте.
  • Посмотрите, является ли Cookie-домен доменом example.com или .example.com (обратите внимание на период впереди). Если нет, установите .example.com .

Вариант Б: если ваш основной домен и субдомены размещены на разных серверах

  • Измените Cookie-домен через меню администратора конфигурации. Перейдите в System> Configuration> General> Web , как показано на скриншоте.
  • Посмотрите, является ли домен .www.example.com www.example.com или .www.example.com (обратите внимание на период впереди). Если нет, установите его на .www.example.com .
  • В магазине test.example.com установите для домена .test.example.com в тестовой среде.

Или измените это, запустив эти sql запросы.

Для проверки домена cookie используйте следующий запрос select для получения конфигурации:

 SELECT * FROM core_config_data WHERE path = 'web/cookie/cookie_domain'; 

После выполнения вышеуказанного запроса мы получим результаты. Убедитесь, что столбец «значение» совпадает с вашим доменом или нет. Обновите значение, если оно не совпадает с вашим доменом.

Для обновления домена cookie используйте следующий запрос:

 UPDATE core_config_data SET VALUE = "domain.com" WHERE path = 'web/cookie/cookie_domain'; 

Решение 2

Проверьте, имеет ли ваш файл php.ini тот же домен cookie, что и в вашей конфигурации Magento, если не измените его на тот же, что и в конфигурации Magento, как показано ниже:

 cookie\_domain = example.com 

Решение 3

Это не рекомендуемый подход, но если все параметры не удаются, вы можете попробовать этот код, изменив параметр, изменив adminhtml cookie adminhtml для поддоменов. Скопируйте файл action.php и сохраните его в том же пути к папке, что и локальный, чтобы ваш основной файл кода можно было переопределить.

В файл app/code/core/Mage/Core/Controller/Varien/Action.php необходимо внести два изменения.

В функции preDispatch измените эти строки:

 /** @var $session Mage_Core_Model_Session */ $session = Mage::getSingleton('core/session', array('name' => $this->_sessionNamespace))->start(); 

Для того, чтобы:

 $namespace = $this->_sessionNamespace.($_SERVER['SERVER_NAME']=='subdomain.example.com'?'_subdomain':''); /** @var $session Mage_Core_Model_Session */ $session = Mage::getSingleton('core/session', array('name' => $namespace))->start(); 

В функции setRedirectWithCookieCheck измените:

 /** @var $session Mage_Core_Model_Session */ session = Mage::getSingleton('core/session', array('name' => $this->_sessionNamespace)); 

Для того, чтобы:

 $namespace = $this->_sessionNamespace.($_SERVER['SERVER_NAME']=='subdomain.example.com'?'_subdomain':''); /** @var $session Mage_Core_Model_Session */ $session = Mage::getSingleton('core/session', array('name' => $namespace)); 

После этого найдите следующий текст во всех файлах:

 Mage::getSingleton('core/session', array('name' => 'adminhtml'));` 

Если обнаружены какие-либо случаи, замените их на:

 Mage::getSingleton('core/session', array('name' => 'adminhtml'.($_SERVER['SERVER_NAME']=='subdomain.example.com'?'_subdomain':''))); 

Причина № 3: Двойные входные куки-файлы, вызывающие периодические проблемы со входом

В некоторых сценариях существует возможность создания системой нескольких файлов cookie, что не позволяет системе войти в систему.

Сценарий 1

Если ваша система Magento имеет одинаковую конфигурацию для вашего основного домена и субдомена в конфигурации Magento, и если пользователь входит на оба сайта, Magento создает два файла cookie. Один имеет значение «Доменное значение» с основным доменом, а другой с поддоменом. Таким образом, у нас будет два сеанса cookie-файлов, поэтому мы не сможем войти в систему.

Решение

Измените настройку Cookie Domain на .example.com для конфигурации домена и субдомена.

Сценарий 2

В этом сценарии, скажем, в вашем php.ini домен cookie не настроен, а значение домена Magento на example.com настроено. Теперь, когда пользователь входит в систему через www.example.com , система создает файл cookie со значением значения домена example.com из конфигурации Magento. Когда пользователь выходит из системы, Magento сгенерирует файл cookie со значением домена по URL-адресу, к которому был получен доступ (например, www.example.com ), поскольку в php.ini домен cookie не был указан. Обратите внимание, что если пользователь входит в систему с помощью example.com или в файле php.ini настроен домен cookie, проблем не возникает.

Решение 1

Добавьте домен cookie в ваш файл php.ini который совпадает с вашим конфигом Magento.

 session.cookie\_domain = example.com 

Решение 2

Измените Домен .example.com на .example.com для конфигурации домена и субдомена.

Примечание. Используйте наш скрипт cookieTest.php чтобы узнать, есть ли у вас файлы cookie с двойным интерфейсом.

Причина № 4: Не удалось создать (прочитать) идентификатор сеанса

 Recoverable Error: session\_regenerate\_id(): Failed to create(read) session ID: user (path: /var/lib/php/sessions) in app/code/core/Mage/Core/Model/Session/Abstract/Varien.php on line 492 

Это ошибка, которую вы можете увидеть в журнале исключений, и она может возникнуть только для PHP7, так как PHP7 выполняет строгую проверку типов.

Решением для этого является изменение функции чтения ядра Magento путем приведения типов. Подробнее об этом здесь .

 public function read($sessId) { //return $data; return (string)$data; } 

Причина № 5: Файл данных сеанса не создан вашим пользователем

 Warning: session_start(): Session data file is not created by your uid in app/code/core/Mage/Core/Model/Session/Abstract/Varien.php on line 125 

Решение 1

Эта ошибка возникает, если вы сохраняете сеансы в файлах, а папка или файлы не имеют разрешения пользователя веб-сервера. Так, в случае nginx, если пользователь вашего веб-сервера — www-data, вам нужно предоставить право владения папке, используя:

 sudo chown -R www-data:www-data 

Решение 2

Если вы работаете в Vagrant, вам может потребоваться убедиться или изменить путь к файлу сессии.

Решение 3

Другая причина в том, что в папке var/sessions могут быть старые сеансы — удалите их и проверьте, решает ли это проблему.

Примечание. Если у вас есть возможность использовать других поставщиков сеансов, переключитесь на другого. Например, перейти от Redis к файлу. Очистите папку var/cache и посмотрите, работает ли она — и снова, попробуйте только это в вашей среде разработки.

Скрипт PHP для обнаружения проблем с cookie

 <?php ini_set('display_errors', 1); $mageFileName = getcwd() . '/app/Mage.php'; require $mageFileName; Mage::app(); echo "<b> Server Cookie Domain Configuration : </b> ".ini_get('session.cookie_domain')."<br>"; foreach (Mage::app()->getStores() as $store) { echo "<b>" . $store->getName() . "</b><br>"; $configCookieDomain = Mage::getStoreConfig('web/cookie/cookie_domain', $store->getId()); $storeConfigUrl = Mage::getStoreConfig('web/unsecure/base_url', $store->getId()); $sourceUrl = parse_url($storeConfigUrl); $storeDomain = $sourceUrl['host']; $cookieDomainResult = ($configCookieDomain == $storeDomain || $configCookieDomain == '.' . $storeDomain) ? "" : "not"; echo "Config cookie Domain : " . $configCookieDomain . " and Store Domain: " . $storeDomain . " " . $cookieDomainResult . " configured properly<br>"; } //echo "<b>Request Cookies:</b> "; $requestCookie = Mage::app()->getRequest()->getHeader('cookie'); $requestCookieArr = explode(';', $requestCookie); $sessionIds = array(); foreach ($requestCookieArr as $requestCookieItem) { $cookieValue = explode('=', $requestCookieItem); // echo $requestCookieItem."<br>"; if (trim($cookieValue[0]) == 'frontend' || trim($cookieValue[0]) == 'adminhtml') { $cookieName = trim($cookieValue[0]); $sessionId = trim($cookieValue[1]); $sessionIds[$cookieName][] = $sessionId; } } $areas = array("frontend", "adminhtml"); foreach ($areas as $area => $cookieName) { echo "<b>validating " . $cookieName . " cookie </b><br>"; $cookieExpires = Mage::getModel('core/cookie')->getLifetime($cookieName); $cookiePath = Mage::getModel('core/cookie')->getPath($cookieName); $cookieDomain = Mage::getModel('core/cookie')->getDomain($cookieName); $cookieSecure = Mage::getModel('core/cookie')->isSecure($cookieName); $cookieHttpOnly = Mage::getModel('core/cookie')->getHttponly($cookieName); echo "Cookie Lifetime : " . $cookieExpires . " <br>"; echo "Cookie Path : " . $cookiePath . " <br>"; echo "Cookie Domain : " . $cookieDomain . " <br>"; echo "Cookie Is Secure : " . $cookieSecure . " <br>"; echo "Cookie Httponly : " . $cookieHttpOnly . " <br>"; if (count($sessionIds[$cookieName]) > 1) { echo "<span style='color:red'><b>We have " . count($sessionIds[$cookieName]) . " " . $cookieName . " Cookies with values : </b>" . implode(',', $sessionIds[$cookieName]) . "<br>"; //$encryptedSessionId = Mage::getSingleton("core/session")->getEncryptedSessionId(); $encryptedSessionId = Mage::getModel('core/cookie')->get($cookieName); echo "Original Cookie value : " . $encryptedSessionId . "<br>"; echo "Please verify the Subdomain and Main Site Cookie Domain Configuration</span><br>"; } } ?> 

Выход:

 Magento Store EN Config cookie Domain : staging.abc.com and Store Domain: staging.abc.com configured properly Magento Store FR Config cookie Domain : staging.abc.com and Store Domain: staging.abc.com configured properly validating frontend cookie Cookie Lifetime : 31536000 Cookie Path : / Cookie Domain : staging.zeb.be Cookie Is Secure : Cookie Httponly : 1 validating adminhtml cookie Cookie Lifetime : 31536000 Cookie Path : / Cookie Domain : staging.zeb.be Cookie Is Secure : Cookie Httponly : 1