最近由于项目的需要研究了一下康胜的Ucenter这个产品,并动手把Discuz和Drupal整合了一下,实现了用户数据以及登陆登出的一致。用PHP实现单点登陆来说,康胜的方案算是一个不错的选择,其中有些想法还是蛮有新意的,值得学习下。先来说说Ucenter实现多个应用同步登陆的原理:
Ucenter里面每个应用都有自己唯一的应用ID和通信密匙,用户在其中的一个应用中登陆时,先用uc_user_login去检查该用户是否在Ucenter的用户中的密码和用户名是否正确,如果正确则回用户的uidemail等信息,如果返回的uid大于0则成功登陆Ucenter,菩镟的各个状态见开发文档,然后调用uc_user_syn_login($uid)去实现同步登陆,该函数会生成一段js代码,你在完成登陆的流程后必须把这段代码输出到页面中,以便达到Ucenter通知各个允许同步登陆的应用完成登陆,这段js代码就是去加载一个js 的脚本,这个脚本就是各个应用的api下的uc.php中同步登陆接口的实现,这个脚本根据url参数中带一串加密(根据你在后台自己填写的密匙生成)过后的数据,解密后这个数据中带有用户登陆时输入的用户名和密码等参数,这个时候会生成一个uc_note的对象,去调用他synlogin的方法,并把用户名和密码传过去完成其他各个应用的登陆。这样就实现了同步登陆。
$uc_note = new uc_note();
exit($uc_note->$get['action']($get $post));
$uid = $get['uid'];
$username = $get['username'];
if(!API_SYNLOGIN) {
return API_RETURN_FORBIDDEN;
}
//note 同步登录API 接口
登陆你自己的应用程序的代码 ,一般是写Session 之类的操作啊。Discuz中如让果在自己应用的数据库中检查不到该用户名则生成一个loginuser的cookie以便用户在访问discuz时提示用户去激活,从而把用户信息数据记录到Discuz自己的用户中表
同步登陆的关键点就在于生成的那段js代码,这个想法还是很有才的。
同步登陆过程出可能出现的问题:
可能由于历史数据的原因,各个应用整合前后用户在Ucenter中存在了,但是在其他应用中不存在,这个时候实现登陆时你会发现在uc.php总的synlocugin这个函数里面没法实现登陆,这个问题我遇见了,于是我想Discuz不也用的这个东东吗?我就看了下Discuz的代码中是如何解决这个问题的,结果我发现当在ucenter中用户存在,但是在Discuz中用户不存在时就生成一个cookie当用户去访问应用时如果检测到这个cookie就让用户自己去激活一下,在激活的同时把用户信息记录到自己应用的用户数据库表中,或者用户登陆时没有相应的用户名则也要用户激活以便把用户数据记录下来。
不过后来我想了下,稍微修改下这个代码貌似就可以不用激活了,要是出现这种情况直接直接把用户数据写入自己应用的用户数据库中,用户在自己应用这边登陆时如果能够成功登陆上Ucenter却检查到在自己的应用数据库表中不存在该用户时,也直接把用户名和密码等数据写入到数据库中也可以解决该问题。