IE下ECMall与UCenter等无法同步登录问题初探

2016-07-07 16:49 来源:www.chinab4c.com 作者:ecshop专家

本文核心提示:

(1) 对于站长而言,关注的应该是用户账户是否已经整合成功的问题,而不是“是否能够同步登录”的问题;甚至,应该在UCenter中关闭与ECMall的同步登录。
(2) 对于开发组而言,应该密切留意IE8相对于IE6、IE7的运作机制变化所带来的安全挑战。建议引入两个安全功能:“访问与交易/管理Session Cookies分离”和“交易/管理密码”。


回答:
前言
在ECMall论坛上,有相当部分的站长反映整合UCenter后,在IE下无法同步登录的问题。排除服务器和网络传输问题,客户端浏览器版本甚至用户操作习惯是否也是出现这个问题的重要因素呢?本文就此问题进行初步探讨,并提出一些个人建议。
本文与好友CS1.3共同测试完成。由于我们对该程序接触时间不长,也许有考虑不周的地方,故请各位特别是ECMall开发组给予本文问题的指点,在此先不胜感激。


测试方法与问题提出
测试方法:从快速启动栏启动三个IE窗口(空白页),窗口A打开Discuz! 7.0.0并登录到普通用户帐号后,在窗口B打开DeDeCMS 5.3观察是否同步登录成功,在窗口C打开ECMALL 2.1观察是否同步登录成功。
问题:IE6中,DeDeCMS同步登录成功,ECMALL同步登录失败;IE8中,DeDeCMS和ECMall均能同步登录成功。


IE6同步登录失败


IE8同步登录成功


一、 UCenter同步通知登录机制
UCenter同步通知登录机制采取了服务器端进行远程HTTP通讯、客户端触发http通知相结合的方式。

根据UCenter的开发手册[1],任何程序要进行与其它程序的同步登录则必须调用UCenter客户端文件client.php下的uc_user_synlogin函数(非标准顺序图步骤2)。该函数主要用于与UCenter服务器进行远程HTTP通讯,具体为被执行后:

- 调用uc_api_post函数,命令当前应用所在服务器远程向UCenter服务器发出参数m(module)为user、参数a(action)为synlogin的POST,以请求获取同步登录其它应用的javascript 脚本。(非标准顺序图步骤3)

- UCenter服务端根据POST的参数,运行usercontrol类下面的onsynlogin方法(代码在control\user.php)。若成功,则返回一段能远程触发其它应用程序所在UCenter客户端API接口的javascript 脚本。(非标准顺序图步骤4、截图1)

- 函数最终返回此段js同步登录脚本(非标准顺序图步骤5)。


开发者在得到这段js后,必须将其输出到浏览器(时序图步骤6,截图2),让浏览器通过HTTP方式触发其它应用的同步登录API通知(非标准顺序图步骤7、步骤8),以完成同步登录的目的。



非标准顺序图(时序图个人还没真正去学过,所以这肯定是非标准的)


截图1,iis服务器程序w3wp.exe抓包,反映服务器远程HTTP通讯中,UCenter服务端的请求和响应数据


截图2,Discuz!登录后输出的js同步登录脚本


采取在服务器端与UCenter进行远程HTTP通讯获取js脚本,是一种较为安全稳定的访问方式;但假如服务器不允许函数fsockopen、或者禁止远程通讯(比如IP限制等)的话,那就可能连当前程序登录都成了问题(这也是基于UCenter的产品有相当部分服务器无法正常运行的根源问题所在)。
而采取在客户端触发http通知同步登录的方式,既能尽量地减少程序之间的干扰,也能实现在绝大多数情况下,不需要采取P3P措施就能实现跨域登录。但这种方式也存在局限性,以下情况往往会导致同步登录失败:(1)网络不畅通,无法完整运行和接收js返回信息;(2)当前登录程序跳转太快,导致js运行不完全;(3)浏览器禁止js;(4)多个应用在同一服务器时,运行这段js的效果相当于单个客户端以多个线程方式同时访问同一个服务器,结果加重服务器负担,引起服务器拒绝服务(比如WEB服务器、MySQL线程数限制)。


二、 ECMall的登录机制
ECMall的MVC架构中,app即为Controller,并且所有app都是BaseApp类的派生类。BaseApp类在实例化的初始阶段时,将调用自身方法_init_session()进行session初始化(根据类的继承,所有app类同理也会进行此操作)。而该方法主要任务有:导入session.lib.php、创建对象SessionProcessor、定义常量SESS_ID、和打开session。

SessionProcessor对象一旦被创建后,将对php现有的session机制进行接管(变为session入数据库),并且进行当前浏览者唯一标识ECM_ID(作用与PHPSESSIONID一样)的检查操作。其中有一段代码值得关注,也是本文理解的重点。该段代码为在验证ECM_ID失败、或者不存在时重新生成的操作:
  1. if (!$this->session_id)
  2. {
  3. $this->gen_session_id();

  4. setcookie($this->session_name, $this->session_id . $this->gen_session_key($this->session_id), 0,
  5. $this->session_cookie_path, $this->session_cookie_domain, $this->session_cookie_secure);
  6. }
复制代码
setcookie中的过期参数被设置为0,也就是说,ECM_ID是一个session cookies,在当前浏览器进程关闭后将失效。

作为一款电子商务软件,ECMall考虑的重点之一是如何保证交易的安全,因此在程序设计上,严格限制了无论是cookies还是session的存活时间:首先,所发送的cookies基本全是session cookies;其次,存储在数据库里面的session存活时间只有1440秒(即24分钟)。这样的限定从安全角度而言,其实既合理又较为有效,在只运行一个ECmall的时候也会没有多大问题;然而当需要进行与其它程序的整合和同步登录时,将可能产生以下所说的两种问题:

第一种常见的问题是,用户打开浏览器并登录到论坛(此时自动进行了和ECMall的同步登录),由于某种原因(比如用户自己关闭了浏览器、浏览器崩溃了、突然停电了等等;2038年32位timestamp问题、电脑爆炸和世界末日等原因超出本文讨论范围,不予讨论),浏览器被关闭了;过段时间他重新在这部电脑打开了论坛,此时仍为登录状态,结果一点击商城(ECMall)的页面,就需要重新登录。这个时候该用户可能会抱怨——怎么又让我重新登录?!真麻烦啊。

另外一种则是本文前面的测试方法(也是站长们经常使用的测试手法)。同时打开两个IE,然后登录一边、刷新看另一边有没有登录。然而,为什么IE6/7和IE8差别甚大呢?这要从IE8的运作机制变化说起。

三、 IE8相对于以前版本的运作机制变化

IE8相对于IE7等众多以前的版本,最大的不同之处在于引入了Loosely-Coupled IE(译为“松散耦合式IE”,下面简称LCIE)架构概念[2][3]。作为一种基于作业(Job)的进程管理方式,这种方式已经逐渐被各大浏览器所采用,例如Google Chrome。[4]。


IE8的进程模型

从上面可以看出,IE8比起以前的版本,最大不同处在于存在一个独立的框架进程,用于管理其它tab进程和进行UI交互(通俗可理解为父子进程交互)。
这种模型将会引起两个重要运作机制的变化:

A、进程之间交互影响的变化
在默认情况下,框架进程将管理tab进程的数量。当新建一个IE窗口时(无论是通过开始菜单还是ctrl + N快捷键),框架进程将对新进程进行合并操作(Frame Process Merging),新进程将成为一个tab进程。当然,微软也给了大家选择——如果需要创建一个新的框架进程,则可通过指定参数-nomerge启动IE,或者通过菜单栏的“文件”->“新建会话”来完成。

B、session共享机制的变化
在此模型下,一个IE框架进程内的所有tab进程将共享同一会话(也就是session)。Session对应的session cookies将在框架进程中有一个副本(但不会存储于任何的磁盘等这类介质上)——也就是说,只要框架进程没被结束,session仍将存活。这就是IE8中即使tab进程崩溃也不会对session有任何影响的原因。


由于以上两个运作机制的变化,因此也就不难理解为什么新开窗口进行ECMall与其它程序的同步登录测试中,IE8和其它版本的结果差别甚大了——因为在同步登录下ECMall所生成的session,对于IE6/7新打开的窗口来说并不能共享,因此同步登录失败;而IE8则能共享,因此同步登录成功。

这种模型对于IE8的兼容性和稳定性具有不少的提高。然而假如现有的web网站/程序、特别是极度依赖session安全性的网站/程序没有考虑到这一点,可能会导致程序在会话安全性上面的风险。比如说,病毒若要窃取某网站的session,通常采取插入目标的活动IE进程来监控。在以前常见方式是靠DLL注入方式来完成,而现在则只需要隐藏打开一个IE进程即可——因为框架进程将自动把你打开的进程合并到里面去。事实上对于需要有最大web安全的网站来说,仅仅依靠session也许并不足够。

四、 其它影响
同步登录问题还涉及用户习惯的因素。因为用户习惯将影响进程的寿命,和进程之间的交互影响。由于前面所说的IE8运作机制的变化,事实上用户习惯的影响因素在IE8已经被降低了。详细的不再阐述。
事实上每种测试方法也是一种用户习惯的演练——只不过有些时候站长们(甚至是测试者,比如我)喜欢“越俎代庖”,使用的测试方法不是普通用户常用的习惯,以至导致了同步登录方面的诸多问题。

一、 对于站长而言
由于ECMall设计的特殊性,本质上并不允许同步登录机制的存在。因此站长们的检查重点,应该是用户账户是否已经整合成功的问题,而不是“是否能够同步登录”的问题;甚至,应该在UCenter中关闭与ECMall的同步登录。
若一定要在表面上看得出同步登录的样子,那么则必须确保其它程序有明确指向ECMall的连接,防止用户自行新建窗口打开ECmall。

二、 对于ECMall的开发组而言
由于ECMall下一版本的重点是社区交互,那么同步登录问题也许将成为一个热点。
个人建议,引入“访问与交易/管理Session Cookies分离”(登录特别是同步登录使用短期cookies,而涉及交易则使用session),或者登录密码和交易密码区分的形式(即“交易/管理密码”;用户交易时需要输入交易密码),不失为一种主意。


附录一:测试环境与工具
为排除服务器的影响,使用了两个服务器进行测试并成功达到排除目的。服务器详情如下:
- 服务器A为实际运营的网站,采用WINDOWS 2003 + IIS6 + PHP 5 + MySQL 5架构。
- 服务器B为本地测试使用,采用WINDOWS 2008 R2 + IIS7.5 + PHP 5 + MySQL 5架构。
两套服务器上均单独运行并整合UCenter 1.5 + Discuz! 7.0.0 + DeDeCMS 5.3 + Ucenter Home 2.0 + ECMall 2.1。

为消除浏览器的交叉影响,使用了真实机器上同时跑虚拟机的测试方式;同时每次进行单元测试前,均进行全面的清除缓存操作。具体客户端配置如下:
- 客户端A:虚拟机,WINDOWS XP + IE6
- 客户端B:真实机器,WINDOWS 2008 R2 + IE8
本文所使用的工具有:
- Http Analyzer 5.0
- Process Explorer


附录二:本文参考资料
[1] Monkeye. UCenter 接口开发手册下载 欢迎加入开发爱好者群. 2008-3-26. http://www.discuz.net/thread-879237-1-1.html
[2] IEBlog. IE8 and Loosely-Coupled IE (LCIE). 2008-3-11. http://blogs.msdn.com/ie/archive ... oupled-ie-lcie.aspx
[3] IEBlog. IE8 and Reliability. 2008-7-28. http://blogs.msdn.com/ie/archive ... nd-reliability.aspx
[4] smallfrog. Windows 7 研究——IE8 松散耦合进程框架探索. 2009-4-20. http://blogs.itecn.net/blogs/sma ... /windows-7-ie8.aspx


(全文完)


好文,超详细。
够仔细认真

不 错 误不 错 误

很细心~~~~~~

很少有这么详细积极的热心人 了

真的很好。我也顶一个。

终于出来了,来支持一下~~

你也太牛逼了啊兄弟