magento使用
This article was created in partnership with Ktree. Thank you for supporting the partners who make SitePoint possible.
本文是与Ktree合作创建的。 感谢您支持使SitePoint成为可能的合作伙伴。
In this article are looking at how Magento COOKIEs can create issues with the login functionality of both the customer-facing front-end and admin back-end, the reason it occurs and how it should be resolved.
本文探讨了Magento COOKIE如何在面向客户的前端和管理员后端的登录功能上产生问题,发生的原因以及如何解决。
This is also known as the looping issue, as the screen redirects itself to the same screen, even though the username and password is correct.
这也称为循环问题,因为即使用户名和密码正确,屏幕也会将自身重定向到同一屏幕。
A script is provided at the end of the article which can help detect a few of the issues. Feel free to use and modify as per your needs.
本文末尾提供了一个脚本,它可以帮助检测一些问题。 根据您的需要随意使用和修改。
A COOKIE is a piece of text that a web server can store on a user’s hard drive, and can also later retrieve it. Magento uses COOKIEs in Cart & Backend Admin functionalities, and they may be the source of a few problems when unable to login to Magento.
COOKIE是Web服务器可以存储在用户硬盘上的一段文本,以后也可以检索它。 Magento在Cart&Backend Admin功能中使用COOKIE,当无法登录Magento时,它们可能是一些问题的根源。
A session is an array variable on the server side, which stores information to be used across multiple pages. For example, items added to the cart are typically saved in sessions, and when the user browses the checkout page they are read from the session.
会话是服务器端的一个数组变量,它存储要在多个页面上使用的信息。 例如,添加到购物车中的项目通常保存在会话中,并且当用户浏览结帐页面时,将从会话中读取它们。
Sessions are identified by a unique ID. Its name changes depemnding on the programming language — in PHP it is called a ‘PHP Session ID’. As you might have guessed, the same PHP Session ID needs to be stored as a COOKIE in the client browser to relate.
会话由唯一的ID标识。 它的名称随编程语言的变化而变化-在PHP中,它称为“ PHP会话ID”。 您可能已经猜到过,需要将相同PHP会话ID作为COOKIE存储在客户端浏览器中进行关联。
Magento can store sessions via multiple session providers and this can be configured in the Magento config file at app/etc/local.xml
. These session providers can be chosen here.
Magento可以通过多个会话提供程序存储会话,可以在app/etc/local.xml
的Magento配置文件中对其进行配置。 这些会话提供者可以在这里选择。
File
文件
Database
数据库
Allowing sessions to store themselves in the database is done in /app/etc/local.xml
by adding
.
通过添加
在/app/etc/local.xml
允许会话将自身存储在数据库中。
Magento applications store sessions in the Core\_session
table.
Magento应用程序Core\_session
存储在Core\_session
表中。
Redis
雷迪斯
MemCache
记忆快取
session_save>
Magento uses two different COOKIEs named 'frontend' and 'adminhtml'. The first one is created when any page is browsed. The same COOKIE is also updated whenever the customer logs in, and the next one is created when a backend user is logged in. You can check whether the COOKIEs have been created by clicking Inspect Element > Application, as in the below picture (from Chrome):
Magento使用两个名为“ frontend”和“ adminhtml”的不同COOKIE。 浏览任何页面时都会创建第一个。 每当客户登录时,相同的COOKIE也会更新,而后端用户登录时将创建下一个COOKIE。您可以通过单击Inspect Element> Application来检查 COOKIE是否已创建,如下图(来自Chrome) ):
COOKIEs are configured in Magento via the Configuration admin menu – System > Configuration > General > Web.
通过配置管理菜单- 系统>配置>常规>网络,在Magento中配置COOKIE。
If you haven’t experienced this problem, then you haven’t worked with Magento long enough!
如果您还没有遇到这个问题,那么您与Magento的合作时间还不够长!
This is how it typically happens: when you login by entering your username and password, you will be redirected to the same login page and URL, and your browser is appended with nonce id. This happens for both the customer front-end and the Magento back-end login.
这通常是这样的:当您通过输入用户名和密码登录时,您将被重定向到相同的登录页面和URL,并且您的浏览器附加了随机数ID。 客户前端和Magento后端登录均会发生这种情况。
Let's look at a few reasons why this happens, and how we should resolve those issues.
让我们看看发生这种情况的一些原因,以及我们应该如何解决这些问题。
Let’s say your Magento site is example.com
and the COOKIE domain in Magento is configured as xyz.com
.
假设您的Magento网站为example.com
,而Magento中的COOKIE域配置为xyz.com
。
In this scenario both Magento COOKIEs will set Domain Value
as xyz.com
, but for validating the session Magento will consider the domain through which the site was accessed — in this case example.com
. Since it won’t be able to find an active session with the example.com
domain value, it will redirect the user to the login page even when valid credentials are provided.
在这种情况下,两个Magento COOKIE都会将Domain Value
设置为xyz.com
,但是为了验证会话,Magento将考虑访问站点所通过的域,在本例中为example.com
。 由于它将无法使用example.com
域值来查找活动会话,因此即使提供了有效的凭据,它也会将用户重定向到登录页面。
app/code/core/Mage/Core/Model/Session/Abstract.php
app/code/core/Mage/Core/Model/Session/Abstract.php
After login or logout, the Magento system will regenerate the session using the following script:
登录或注销后,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
app/code/core/Mage/Core/Model/Session/Abstract/Varien.php
Magento will validate the session for every request with the following method:
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;
}
You may normally see this when you migrate your Magento instance from one domain to another domain, for example from Production to Staging, and forget to change the COOKIE domain.
当您将Magento实例从一个域迁移到另一个域(例如从Production到Staging)时,通常会看到此错误,而忘记更改COOKIE域。
Note: you can run the provided COOKIETest.php
script, which validates what the server COOKIE domain is, and what is set in the Magento config.
注意:您可以运行提供的COOKIETest.php
脚本,该脚本验证服务器COOKIE域是什么以及Magento配置中设置的内容。
Solution:
解:
Change the COOKIE Domain via the Configuration admin menu. Go to System > Configuration > General > Web, as per the screenshot.
通过“配置”管理菜单更改COOKIE域。 根据屏幕快照,转到“ 系统”>“配置”>“常规”>“ Web ”。
Alternatively you can change this by running these SQL queries.
或者,您可以通过运行这些SQL查询来更改此设置。
For validating the COOKIE domain use this select query to get the configuration:
为了验证COOKIE域,请使用以下select查询获取配置:
SELECT * FROM core_config_data WHERE path = 'web/COOKIE/COOKIE_domain';
After executing this query, we will get the results. Verify the 'value' column is the same as your domain. Update the value if it is not the same as your domain.
执行完此查询后,我们将获得结果。 确认“值”列与您的域相同。 如果该值与您的域不同,请更新。
To update the COOKIE domain, use this query:
要更新COOKIE域,请使用以下查询:
UPDATE core_config_data SET VALUE = "domain.com" WHERE path = 'web/COOKIE/COOKIE_domain';
Let’s say your site is example.com
. Logging into example.com/admin
works fine.
假设您的网站是example.com
。 登录到example.com/admin
可以正常工作。
But on your staging/QA site, for example staging.example.com/admin
, you are unable to login without deleting all COOKIEs. The system may allow logins to staging.example.com
, but when we login again to example.com/admin
, your next click on staging.example.com
kicks you back to the login page. Similar behavior is experienced for customers using the front-end login as well.
但是,在您的登台/ QA网站上,例如staging.example.com/admin
,如果不删除所有COOKIE便无法登录。 系统可能允许登录到staging.example.com
,但是当我们再次登录到example.com/admin
,您对staging.example.com
的下一次单击staging.example.com
您带回到登录页面。 使用前端登录的客户也会遇到类似的行为。
Option A: If your main domain and subdomains are hosted on the same server
选项A:如果您的主域和子域托管在同一服务器上
Change the COOKIE Domain via the Configuration admin menu. Go to System > Configuration > General > Web, as per the screenshot.
通过“配置”管理菜单更改COOKIE域。 根据屏幕快照,转到“ 系统”>“配置”>“常规”>“ Web ”。
See if COOKIE Domain is example.com
, or .example.com
(note the period in front). If not, set it to .example.com
.
查看COOKIE域是example.com
还是.example.com
(请注意前面的句点)。 如果不是,请将其设置为.example.com
。
Option B: If your main domain and subdomains are hosted on different servers
选项B:如果您的主域和子域托管在不同的服务器上
Change the COOKIE Domain via the Configuration admin menu. Go to System > Configuration > General > Web, as per the screenshot.
通过“配置”管理菜单更改COOKIE域。 根据屏幕快照,转到“ 系统”>“配置”>“常规”>“ Web ”。
See if the COOKIE Domain is www.example.com
, or .www.example.com
(note the period in front). If not, set it to .www.example.com
.
查看COOKIE域是www.example.com
还是.www.example.com
(注意前面的句点)。 如果不是,请将其设置为.www.example.com
。
In the test.example.com
shop, set the COOKIE Domain to .test.example.com
on the test environment.
在test.example.com
店,设置COOKIE域到.test.example.com
测试环境。
Alternatively, change this by running these sql queries.
或者,通过运行这些sql查询来更改此设置。
For validating the COOKIE domain use the following select query to get the configuration:
为了验证COOKIE域,请使用以下选择查询来获取配置:
SELECT * FROM core_config_data WHERE path = 'web/COOKIE/COOKIE_domain';
After executing the above query we will get the results. Verify whether the 'value' column is the same as your domain or not. Update the value if it is not same as your domain.
执行完上面的查询后,我们将得到结果。 验证“值”列是否与您的域相同。 如果该值与您的域不同,请更新。
For updating the COOKIE domain, use the following query:
要更新COOKIE域,请使用以下查询:
UPDATE core_config_data SET VALUE = "domain.com" WHERE path = 'web/COOKIE/COOKIE_domain';
Check whether your php.ini
file has the same COOKIE domain as in your Magento config — if not change it to the same as the Magento config, as below:
检查您的php.ini
文件是否具有与Magento配置中相同的COOKIE域-如果未将其更改为与Magento配置相同,如下所示:
COOKIE\_domain = example.com
This is not the recommended approach, but if all options fail you can try this code, changing the option by changing the adminhtml
COOKIE name for subdomains. Copy the file action.php
and keep it in the same folder path as local so your core code file can be overridden.
这不是推荐的方法,但是如果所有选项都失败,则可以尝试以下代码,通过更改子域的adminhtml
COOKIE名称来更改选项。 复制文件action.php
并将其保留在与本地相同的文件夹路径中,以便可以覆盖您的核心代码文件。
There are two changes to make in the file app/code/core/Mage/Core/Controller/Varien/Action.php
.
在文件app/code/core/Mage/Core/Controller/Varien/Action.php
。
In the preDispatch
function, change these lines:
在preDispatch
函数中,更改以下行:
/** @var $session Mage_Core_Model_Session */ $session = Mage::getSingleton('core/session', array('name' => $this->_sessionNamespace))->start();
To:
至:
$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();
In the function setRedirectWithCOOKIECheck
, change:
在函数setRedirectWithCOOKIECheck
,更改:
/** @var $session Mage_Core_Model_Session */ session = Mage::getSingleton('core/session', array('name' => $this->_sessionNamespace));
To:
至:
$namespace = $this->_sessionNamespace.($_SERVER['SERVER_NAME']=='subdomain.example.com'?'_subdomain':''); /** @var $session Mage_Core_Model_Session */ $session = Mage::getSingleton('core/session', array('name' => $namespace));
After that, search for the following text in all files:
之后,在所有文件中搜索以下文本:
Mage::getSingleton('core/session', array('name' => 'adminhtml'));`
If any occurrences are found, replace them with:
如果发现任何情况,请将其替换为:
Mage::getSingleton('core/session', array('name' => 'adminhtml'.($_SERVER['SERVER_NAME']=='subdomain.example.com'?'_subdomain':'')));
In a few scenarios, there is the possibility of the system creating multiple frontend COOKIEs, which prevents the system from allowing you to login..
在某些情况下,系统可能会创建多个前端COOKIE,这会阻止系统允许您登录。
When your Magento system has the same configuration for your main domain and subdomain in the Magento config, and if the user logs in to both the sites, Magento creates two COOKIEs. One has 'Domain Value' set with the main domain, and another with the subdomain. As such we will have two front-end COOKIE sessions, so we won't be able to login to the system.
当您的Magento系统在Magento配置中的主域和子域具有相同的配置时,并且如果用户登录到两个站点,则Magento将创建两个COOKIE。 一个在主域中设置了“域值”,另一个在子域中设置了“域值”。 因此,我们将有两个前端COOKIE会话,因此我们将无法登录到系统。
Solution
解
Change the COOKIE Domain setting to .example.com
for both the domain and subdomain configurations.
将域和子域配置的COOKIE域设置更改为.example.com
。
In this scenario, let’s say in your php.ini
, no COOKIE domain is configured and the Magento Domain Value of example.com
is configured. Now when the user logs in via www.example.com
, the system creates a COOKIE with a Domain Value of example.com
from the Magento config. When the user logs out, Magento will regenerate the COOKIE with a Domain Value from the URL accessed (i.e www.example.com
), since in php.ini
no COOKIE domain was specified. Note that if the user logs in using example.com
or a COOKIE domain is configured in php.ini
, no issues will arise.
在这种情况下,假设您在php.ini
,未配置任何COOKIE域,并且未配置example.com
的Magento 域值 。 现在,当用户通过www.example.com
登录时,系统会从Magento配置中创建一个具有example.com
域值的COOKIE。 当用户注销时,Magento将根据访问的URL(即www.example.com
)使用域值重新生成COOKIE,因为在php.ini
未指定COOKIE域。 请注意,如果用户使用example.com
登录或在php.ini
配置了COOKIE域,则不会出现任何问题。
Add a COOKIE domain to your php.ini
file that is the same as your Magento config.
将一个COOKIE域添加到您的php.ini
文件中,该域与您的Magento配置相同。
session.COOKIE\_domain = example.com
Change the COOKIE Domain to .example.com
for both domain and subdomain configurations.
对于域和子域配置,都将COOKIE域更改为.example.com
。
Note: Use our COOKIETest.php
script to see if you have double frontend COOKIEs.
注意:使用我们的COOKIETest.php
脚本来查看您是否有双重前端COOKIE。
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
This is an error you may see in the exception log, and might occur only for PHP7, as PHP7 does strict type checking.
您可能会在异常日志中看到此错误,并且可能仅对PHP7发生,因为PHP7会进行严格的类型检查。
The solution for this is to change the Magento core read function by typecasting. More on this here.
解决方案是通过类型转换来更改Magento核心读取功能。 更多关于此这里 。
public function read($sessId) {
//return $data;
return (string)$data;
}
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
This error occurs if you are saving sessions in files, and the folder or files lack webserver user permission. So in the case of nginx, if your webserver user is www-data, you need to grant ownership to the folder using:
如果将会话保存在文件中,并且一个或多个文件夹缺少Web服务器用户权限,则会发生此错误。 因此,对于Nginx,如果您的Web服务器用户是www-data,则需要使用以下方式授予文件夹所有权:
sudo chown -R www-data:www-data
If you are running on Vagrant, you may have to make sure or change the file session path.
如果您在Vagrant上运行,则可能必须确保或更改文件会话路径。
Another reason is that there could be some old sessions in the var/sessions
folder — delete them and test whether that fixes the problem.
另一个原因是var/sessions
文件夹中可能有一些旧会话,请删除它们并测试是否可以解决问题。
Note: If you have the option to use different session providers, switch to another. For example, go from Redis to file. Clear your var/cache
folder and see if it works — and again, only try this in your development environment.
注意:如果可以选择使用其他会话提供程序,请切换到其他会话提供程序。 例如,从Redis转到文件。 清除您的var/cache
文件夹,看看它是否有效-再次,仅在开发环境中尝试此操作。
ini_set('display_errors', 1);
$mageFileName = getcwd() . '/app/Mage.php';
require $mageFileName;
Mage::app();
echo " Server COOKIE Domain Configuration : ".ini_get('session.COOKIE_domain')."
";
foreach (Mage::app()->getStores() as $store) {
echo "" . $store->getName() . "
";
$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
";
}
//echo "Request COOKIEs: ";
$requestCOOKIE = Mage::app()->getRequest()->getHeader('COOKIE');
$requestCOOKIEArr = explode(';', $requestCOOKIE);
$sessionIds = array();
foreach ($requestCOOKIEArr as $requestCOOKIEItem) {
$COOKIEValue = explode('=', $requestCOOKIEItem);
// echo $requestCOOKIEItem."
";
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 "validating " . $COOKIEName . " COOKIE
";
$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 . "
";
echo "COOKIE Path : " . $COOKIEPath . "
";
echo "COOKIE Domain : " . $COOKIEDomain . "
";
echo "COOKIE Is Secure : " . $COOKIESecure . "
";
echo "COOKIE Httponly : " . $COOKIEHttpOnly . "
";
if (count($sessionIds[$COOKIEName]) > 1) {
echo "We have " . count($sessionIds[$COOKIEName]) . " " . $COOKIEName . " COOKIEs with values : " . implode(',', $sessionIds[$COOKIEName]) . "
";
//$encryptedSessionId = Mage::getSingleton("core/session")->getEncryptedSessionId();
$encryptedSessionId = Mage::getModel('core/COOKIE')->get($COOKIEName);
echo "Original COOKIE value : " . $encryptedSessionId . "
";
echo "Please verify the Subdomain and Main Site COOKIE Domain Configuration
";
}
}
?>
Output:
输出:
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
翻译自: https://www.sitepoint.com/fix-magento-login-issues-COOKIEs-sessions/
magento使用