magento 客户登录失败并重定向到登录页面

上篇文章介绍了cookie和session的使用和注意事项

这通常是这样的:当您通过输入用户名和密码登录时,您将被重定向到相同的登录页面和URL,并且您的浏览器附加了nonce id。对于客户前端和Magento后端登录都会发生这种情况。

让我们看看为什么会发生这种情况的几个原因,以及我们应该如何解决这些问题。

原因#1:Cookie域与服务器域不匹配

假设您的Magento站点是,example.com并且Magento中的cookie域配置为xyz.com

在这种情况下,两个Magento cookie都将设置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 * 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:使用了多个子域,Magento的cookie配置不正确

假设您的网站是example.com。登录example.com/admin工作正常。

但是,例如staging.example.com/admin,在您的暂存/质量检查站点上,如果不删除所有cookie,则无法登录。系统可能允许登录staging.example.com,但是当我们再次登录时example.com/admin,您的下一次点击会将您staging.example.com踢回登录页面。使用前端登录的客户也会遇到类似的行为。

解决方案1

选项A:如果您的主域和子域托管在同一台服务器上

  • 通过“配置”管理菜单更改Cookie域。根据屏幕截图,转到
    System > Configuration > General > Web
  • 查看Cookie域是否为example.com,或者.example.com(请注意前面的句点)。如果没有,请将其设置为.example.com

选项B:如果您的主域和子域托管在不同的服务器上

  • 通过“配置”管理菜单更改Cookie域。根据屏幕截图,转到
    System > Configuration > General > Web
  • 查看Cookie域是否www.example.com,或.www.example.com(请注意前面的句点)。如果没有,请将其设置为.www.example.com
  • test.example.com商店中,将Cookie域设置.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文件是否与Magento配置中的cookie域相同 - 如果不将其更改为与Magento配置相同,如下所示:

cookie\_domain = example.com

解决方案3

这不是推荐的方法,但如果所有选项都失败,您可以尝试此代码,通过更改adminhtml子域的cookie名称来更改选项。复制文件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导致间歇性登录问题

在少数情况下,系统可能会创建多个前端cookie,从而阻止系统允许您登录。

场景1

当您的Magento系统在Magento配置中具有与主域和子域相同的配置时,如果用户登录到这两个站点,Magento会创建两个cookie。一个具有主域的“域值”,另一个具有子域。因此,我们将有两个前端cookie会话,因此我们将无法登录系统。

Cookie域设置更改.example.com为域和子域配置。

情景2

在这种情况下,我们在你说php.ini,没有Cookie域配置和Magento的域值example.com配置。现在,当用户登录时www.example.com,系统会创建一个域值为example.comMagento配置的cookie 。当用户注销时,Magento将使用来自访问的URL(即www.example.com)的域值重新生成cookie ,因为php.ini没有指定cookie域。请注意,如果用户使用登录example.com或配置了cookie域,则php.ini不会出现任何问题。

解决方案1

在您的php.ini文件中添加一个与您的Magento配置相同的cookie域。

session.cookie\_domain = example.com

解决方案2

将Cookie域更改.example.com为域和子域配置。

注意:使用我们的cookieTest.php脚本来查看您是否有双前端cookie。

原因#4:无法创建(读取)会话ID

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:您的uid不会创建会话数据文件

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

如果要在文件中保存会话,并且文件夹或文件缺少Web服务器用户权限,则会发生此错误。因此,对于nginx,如果您的网络服务器用户是www-data,您需要使用以下方式授予该文件夹的所有权:

sudo chown -R www-data:www-data

解决方案2

如果您在Vagrant上运行,则可能必须确保或更改文件会话路径。

解决方案3

另一个原因是var/sessions文件夹中可能存在一些旧会话- 删除它们并测试是否可以解决问题。

注意:如果您可以选择使用其他会话提供程序,请切换到另一个。例如,从Redis转到文件。清除var/cache文件夹并查看其是否有效 - 再次,只在开发环境中尝试此操作。

用于检测Cookie问题的PHP脚本

<?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 
赞(0)
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏

相关文章

Please Login to comment