ECShop与Discuz X2的整合

这几天整合ECShop与Discuz X2,发现了Discuz X2一个简单却很严重的bug,导致单点登录失败。本文使用了ECShop2.7.2,Discuz X2。

 

为了模拟真实环境,特意设置了内部DNS :*.fcy.cn到本机,ECShop使用了mall.fcy.cn的域名,Discuz使用了 www.fcy.cn 的域名。

 

Discuz X2的安装及ECShop的安装,都是按照官方方法,安装完成后,各自能正常工作。使用Discuz X2自带的UCenter 1.6.0,不再单独安装。

 

ECShop的用户整合:复制discuz的uc_client目录至ecshop根目录,进入ecshop的管理后台,进行会员整合。输入UCenter 访问地址:http://www.fcy.cn/uc_server ,注意最后没有'/'。整合成功后,进入discuz的ucenter管理后台,能看到ecshop应用已经成功整合,显示通信成功。另外还有个discuz的应用。ecshop,discuz都是作为ucenter的接入应用。但是,这里有个问题,也就是Discuz X2的bug,ECShop应用的主URL为:http://mall.fcy.cn/ ,注意,后面多了一个'/', 如果不删除,会导致单点登录失败。就是说,要检查各个接入的应用主URL,结尾一定不能含有'/'。至此,成功完成单点登录的配置,可以在任意一个子应用完成单点登录和退出。

 

原理:

一,用户关系
1,UCenter用户表:
ucenter_members,所有用户表,含管理员用户。所有子系统注册的用户都会加入到本表。
ucenter_mergemembers,接入系统导入的用户,如从ECShop导入的用户。
ucenter_admins,UCenter的管理员用户,与ucenter_members关联,非独立用户表。

2,Discuz用户表:
common_member,论坛系统的用户。来自UCenter的用户登录,激活后,在此表产生用户数据。

3,ECShop用户表:
users,ECShop系统的用户。来自UCenter的用户登录,直接在此表产生用户数据。

 

二,单点登录处理

参考http://xuebingnanmm.iteye.com/blog/627840,其中有些具体文件名称和本文使用版本不同。

部分摘录,适当修改:

1,用户登录bbs,通过logging.php文件中,使用函数uc_user_login验证,如果验证成功,将调用函数uc_user_synlogin(位于uc_client下的client.php文件中),在这个函数中调用 uc_api_post('user', 'synlogin', array('uid'=>$uid));之后向UC_API.'/index.php'传递了数据;这里的UC_API就是在config/config_ucenter.php中的定义的uc_server之URL地址。
2,uc_server的index.php接受参数数据,获得model为user,action为synlogin,就调用control目录下的user.php类中的onsynlogin方法,通过foreach循环,以javascript的方式通知uc应用列表中的应用同步登录;即通过get方式传递给应用目录中api下的uc.php一些数据;
3,uc.php接收通知并处理get过来的数据,并在函数synlogin(位于uc.php中)通过函数_authcode加密数据(默认以UC_KEY作为密钥),用函数_setcookie设置cookie。为了确保cookie能够成功写入,不会被浏览器的安全隐私设置拦截,使用了P3P协议。
4,各个应用在适当的文件中用对应的密钥解码上面设置的cookie,得到用户id等数据;通过这个值来判断用户是否经过其它应用登录过。

 

附修改过的test.php(使用的用户id为1),作为一个单点登录应用来测试。

 

<?php
include_once "./config/config_ucenter.php";
include_once "./uc_client/client.php";
echo uc_user_synlogin(1);
echo "<pre>";
var_dump($_COOKIE);
echo "</pre>";
?>

<script type="text/javascript">
var obj=document.getElementsByTagName("script");
for(var i=0;i<obj.length-1;i++) {
document.write("<a href=\""+obj[i].src+"\">"+obj[i].src+"</a><hr>");
}
</script>

你可能感兴趣的:(discuz)