未来往事
Discuz UCenter通信原理与用户免激活同步登录
本文阐述了Discuz UCenter用户中心数据自动同步其他通信应用 免去用户激活 批量激活站点整合用户相关的原理与实现方法。

最后更新:2013/04/08
新版本可以论坛程序后台——ucenter中设置直接激活即可(但不能数据同步)。


本文档基于DiscuzX2.0环境所写。原则上兼容X1.5/X2.5版本的Discuz!X,毕竟这里本人未对其他版本进行测试,如用于X2.0之外的其他版本,请谨慎操作,以免造成不可能挽回的结果。

Ucenter通信原理:
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.inc.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;

4、各个应用在适当的文件中用对应的密钥解码上面设置的cookie,得到用户id等数据;通过这个值来判断用户是否经过其它应用登录过;
点击在新窗口中浏览此图片

以discuz举例:
一、用户登录检查与用户登录验证logging.php
在bbs的logging.php中如下代码段

检查用户id变量$discuz_uid是否为空来判断,用户是否登录(包括从别的应用登录。)
如果用户从bbs登录,则在登录验证成功后通过如下代码:
$ucsynlogin = $allowsynlogin ? uc_user_synlogin($discuz_uid) : '';

通知其它应用----“用户已从bbs登录,请通知其它应用设置cookie”
(uc_server通过javascript调用方式向其它应用的api/uc.php传递数据)
可以在uc应用目录下新建一个名为test.php的文件,来模拟登录成功,请求uc_server通知其它应用。文件内容为:

PS:这段测试代码还可以测试同步登录不好使的情况,具体使用方法,你可以思考一下(本文后面也有介绍),有问题可以在此文结尾发表评论与我讨论。
运行后,查看源代码即可看到javascript;
这里要注意了:这些javascript的通知中是不包含用户登录的应用的。也就是说只"通知"用户未登录的应用,因为用户通过uc_server登录成功的当前应用,当然不需要uc_server再通知了。具体代码请参看:webroot\uc_server\control\user.php中的onsynlogin函数的这句:
if($app['synlogin'] && $app['appid'] != $this->app['appid'])
代码解释:
$app['synlogin']是uc应用是否允许同步登录
而且应用id不等于用户当前登录的应用id
$app数组就是uc_server\data\cache\apps.php中的数组$_CACHE['apps'];
$this->app就是用户登录的应用

二、接受其它应用的同步登录通知:
在discuz的api目录下的uc.php中的函数synlogin,在这里接受uc_server发送过来的“同步登录通知”,并设置discuz的cookie,在这个函数中你可以查看到cookie的加密密钥的“算法”;
如果你想看看uc_server发送过的的“通知”是什么数据,你可以这么做:
1、修改要接受通知的应用目录下的api\uc.php,在$action = $get['action'];代码下面添加如下代码:
echo "<pre>";var_dump($get);echo "</pre>";die("<hr>api\uc.php");

2、将上面建立的test.php文件放置在其它允许同步登录的应用目录下,并在浏览器中运行,然后点击页面中对应第一步的应用链接,即可看到uc_server“通知”给改应用的数据;

三、检查用户是否已登录(无论是那个应用下登录):
discuz的include目录中common.inc.php中有这样的代码:

这段代码就是解码在uc.php中用密钥($discuz_auth_key)加密的cookie值,以获得用户id($discuz_uid)
这里的解密函数位于bbs\include\global.func.php中,虽然未给函数传递cookie密钥,但函数中通过全局变量$GLOBALS['discuz_auth_key'])获得密钥。

Ucenter App通信详细过程如图:
点击在新窗口中浏览此图片





DiscuzX2.0 论坛UC用户数据自动同步其他应用,免其他站点用户激活修改方法
修改文件:/api/uc.php

修改该函数定义如下:
作者:Rinald @『未来往事 | 记录生活,存储回忆!
原文地址:http://fity.cn/post/238/
本站采用「署名 4.0 国际(CC BY 4.0)」创作共享协议。通俗地讲,只要在使用时署名,那么使用者可以对本站所有原创内容进行转载、节选、混编、二次创作,允许商业性使用。除非在文章正文内单独说明,本站欢迎各种形式的转载。互联网技术更新很快,本站很多文章都具有实效性,我会及时更新原文,但转载的文章无法通知更新。为了不给读者造成困惑或误导,请大家在转载时保留此出处信息。
hwq1234
2016/08/10 09:50
ucenter可以进行数据同步吗,a项目的user表和b项目的user表部分数据(用户名,密码,邮箱一致),当a项目user表的用户名密码或邮箱修改时,b项目对应的也会进行修改,反之亦然。ucenter能够做到吗?
Rinald 回复于 2016/08/11 09:59
欢迎来访未来往事博客。如果是多论坛可以基于ucenter进行整合;如果是uc与其他程序项目可以使用uc api进行开发接入。
zpl89898989
2015/01/27 16:13
很好,能用!解决了我的问题。
自动激活
谢谢啊大神
Rinald 回复于 2016/08/11 10:01
对你有所帮助就好,欢迎常来~~
海天 Homepage
2012/08/27 18:01
X2.5 貌似不行啊?
Rinald 回复于 2012/08/28 12:22
你测试过了吗?这篇文档是基于X2写的,当时为了解决X2多站点用户激活问题写的。X2.5未经过测试。
第1页 / 共1页 第一页 1 最后页
发表评论
  昵称 [注册]
  密码 (游客无需密码)
  网址
  电邮(电子邮件地址不会被公开, 仅用于接收评论回复提醒使用)
OpenID登入 权限选项 表情