首页 > 技术笔记 > php > Magento Session过早实例化的危害
2014
08-31

Magento Session过早实例化的危害

    问题描述:magento的cookie没有frontend或者adminhtml,只有PHPSESSID

    这周我们看magent系统错误深处的核心代码。 我才发现自己的错误,但是很快就会检查和修复我的扩展。

    简而言之,就是如果你在Magento的请求生命周期过早的使用session对象,你可能会打破系统session存储。

Magento和PHP Session Cookies

    如果你仔细查看magento商城系统的cookie你会发现,一个cookie名字为adminhtml,另一个叫为frontend。

magento cookies

    这里是假设你在前台访问了页面,并且你在后台也登陆了管理页面,这些cookie的值是一段看起来很难理解的字符串。

     这是PHP的Session ID,HTTP是无状态的协议——Web系统存储访问状态的方式是在浏览器中设置一个唯一ID的cookie,然后通过这个唯一的ID去查系统Session值。在Magento中,这个数据是存储在数据库中的 core_session表中,或者以文件存储在var/session 中。也可能存储在 redis中。


    cookie的名称是非常重要的。当magento初始化它的sessions时,它使用PHP的 session_name函数来为session设置一个自定义的名称,设置的cookie的名称将用来查询session_id,magento为当前的域(前台frontend或后台adminhtml)设置这个值。这个重要的方法代码如下:

     请注意,magento实例化core/session有一个name参数,这个参数就是目前所在的域,并且每个控制器都会设置。


    $_sessionNamespace的值最终被调用,并且叫做session_name。


    因此,magento在session系统的上层创建了一个抽象层,允许使用不同的session值,并且为不同的域设置cookie。后台使用一组和前台完全不同的session。虽然这个设计和这个系统的目的好的,但是却有一定的缺陷。


过早的Session实例化

    magento在运行到 preDispatch方法时才知道自己现在是在前台还是在后台,因此magento在运行preDispatch方法之前是绝对不可以让session实例化的。不过在session实例化之前有一些事件是非常危险的,如果开发者在开发功能时监听这些事件,并且在实例化了session,那么可能会造成一些奇怪现象的发生。

    看一下这个模块,他设置了一个监听事件,用来监听controller_front_init_before这个事件(也有一些人把这个叫钩子)。

    并且创建了一个事件监听的方法,在这里面实例化了core/session


     如果你访问pulsestorm_sessionareabug/index/special(这个例子中,在preDispatch实例化了session),再来看看你系统中的cookie。

magento sessid

    你会看到一个名为PHPSESSIDcookie,当magento在实例化session时如果不知道现在是在前台还是后台, session_name函数就不会被调用,而是设置一个默认的session。这显然是不正确的。

后果

    这样做的后果不一定是灾难性的,但是却非常微妙。并且magento会报很多“the behavior only happens intermittently”这样的错误。

    如果你在前台或者后台都提前实例化了session的话,那么你的前台和后台便会公用一个cookie,如果其中一个域要设置新的值,那么之前的值就会被清除了。

    当过早的实例化Session的话,有时cookie的名称会变成PHPSESSID,最终导致magento读取到的不是正确的值,而引起一些错误。

    如果你要登录后台必须先清理掉cookie之后才能登录的话,那么这个错误很可能就是罪魁祸首。

修复

    很抱歉,这里没有比较好的修复方法。如果你是magento插件的作者或者开发者的话,如果你要进行session实例化操作的话,你应该避免在core/session实例化之前,监听下面这些事件进行操作。

     下面这些使一些在 preDispatch之前的比较危险的事件,你也要小心这些事件。


    这些事件在preDispatch之前或者之后触发过无数次。所以如果你在preDispatch之前有这样的错误的代码,一定要小心。


     很不幸,如果你是一个magento商城系统的所有者的话,除了停止使用这个扩展之外没有更好的方法。如果你怀疑你的网站存在这样的问题,在magento的代码中Mage_Core_Model_Session_Abstract_Varien中有附加日志:


    查看日志,如果有这样的记录你可能需要修改你使用的扩展。


    希望magento可以在2.0版本中对这样的问题有所修复,不过如果使用1.*的版本的话,我们肯定得注意这样的问题了!

最后编辑:
作者:射雕天龙
转载请注明:转载自射雕天龙的博客(http://blog.wangjunfeng.com)
捐 赠如果您觉得这篇文章有用处,请支持作者!鼓励作者写出更好更多的文章!

Magento Session过早实例化的危害》有 3 条评论

  1. 小黎 说:

    沙发~~

留下一个回复

你的email不会被公开。