2015-05-19 14:23:01
接着上一篇文章,上一篇里我们讲到了我们的网站和Ucservice通信成功,以及discuz和Ucservice通信成功,下面我就来看看如果让自己的网站和discuz进行同步的登陆和退出。首先,先了解下内部的执行流程以及简单的理解下原理:
1.当某一个应用的某一个会员登陆(或退出)成功,这个应用通知到Ucenter Service,告诉UC,有人登陆了!UC接收到请求后,查看有哪些应用需要同步登陆,然后发送请求到这些应用下的api目录的uc.php(文件名可 以修改设置)。到此,Ucenter Service的工作就完成了。
2.uc.php接收到Ucenter Service发来的请求后,根据参数调用相应的操作进行本应用的同步登陆或退出。这样完成了,其他应用同步到本应用。
3.本应用同步到其他应用。用户登陆成功后,调用相应的uc client api函数 通知到uc service,再由Uc service 通知其他应用,整个流程有点像一个数据结构中的“单向循环链表”。当然,这样的比喻并不是很恰当,
看图是比较简单,但内部原理还是比较复杂的。下面是实例代码:
1.接收通知,同步登陆:
打开api/uc.php ,找到function synlogin($get, $post) ,其他的应用登陆后,就会执行这个函数,URL参数通过$get,$post传递进来。
然后,如:
$uid = intval($get['uid']); //获取用户ID ,注意,此ID是UC中的id
$username = $get['username']; // 获取用户名
通过这些参数判断是否登陆自己的,具体的业务逻辑根具体的应用相关,一般来说,就是查找本应用中是否有相应的用户名,如果有就登陆,没有,就可不做任何操作,也可直接添加此用户到数据库。下面是列子:
function synlogin($get, $post) {
$uid = intval($get['uid']);
$username = $get['username'];
if(!API_SYNLOGIN) {
return API_RETURN_FORBIDDEN;
}
header(‘P3P: CP=”CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR”‘);
$Bakeso = new Bakeso();
$ucconn = $Bakeso->ucconn();
$sql = “SELECT id,user_name,password FROM think_user WHERE user_name=’$username’”;
$userInfo = $Bakeso->getRow($sql); //获取到用户信息
if($userInfo['id'] > 0){
session_start();
$_SESSION['login_ucenter']['login'] = 1; //设置SESSION
$_SESSION['login_ucenter']['userInfo'] = $userInfo;
}else{
//…
}
}
2.接收通知,同步退出:
api/uc.php ,找到function synlogout()
退出比较简单,就是销毁SESSION或者COOKIE。
function synlogout($get, $post) {
if(!API_SYNLOGOUT) {
return API_RETURN_FORBIDDEN;
}
//note 同步登出 API 接口
header(‘P3P: CP=”CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR”‘);
session_start();
unset($_SESSION['login_ucenter']);
unset($_SESSION['userInfo']);
}
3.登陆后通知到Ucservice 由Ucservice通知其他应用。
假定有function checklogin() 处理用户登陆的话,接收到用户名和密码后有两种情况,一种是登陆成功,一种失败,
登陆成功后,我们调用uc_client/client.php 的 uc_user_login()再次登陆 UCenter,uc_user_login()返回用户的一些信息,这些信息用于获取同步登陆通知代码,采用uc_user_synlogin()函数 获取。看下面代码示例:
list($uid, $username, $password, $email) = uc_user_login($user_name, $md5Password); // 获取用户信息
if($uid > 0){ //大于0表示Ucenter存在此用户
setcookie(‘Example_auth’, uc_authcode($uid.”t”.$username, ‘ENCODE’));
$ucsynlogin = uc_user_synlogin($uid); //获取通知代码
}
获取到通知代码后,因为代码是一段JS代码,echo 输出到浏览器,在浏览器没有任何的表现,浏览器再发送请求都ucservice。这样就实现异步通知。其他的应用接收到通知后进行相应的同步登陆处理。
这只是登陆应用成功的时候做的处理,那如果登陆不成功呢?假设我在discuz里注册了一个会员,这个时候到自己的网站里登陆是肯定登陆不成功的,除非实 现了同步注册,这里不讨论这个,因为大多数情况下,每一个应用的注册项是不同的。比如说,我在论坛里注册只需要email,用户名,密码,但我在自己的网 站里注册却需要填写公司名称。所以,同步注册是不太可能的。那么,我就要判断,这个会员是不是已经在别的应用中注册过,并且用户名和密码都是正确的,如果 是正确的,那么我们让他跳转到“激活”页面,填写一些注册信息后,加到自己网站的数据库用户表里,用户登陆一次。下面就是登陆失败后判断会员是否已经在 Ucenter中:
list($uid, $username, $passwordReturn, $email) = uc_user_login($user_name, $md5Password); //登陆一次UCENTER
if($uid > 0){ // 大于0表示存在此用户
$_SESSION['activates']['user_name'] = $username;
$_SESSION['activates']['password'] = $password;
$_SESSION['activates']['email'] = $email;
header(“Location:”.$url); //跳转到激活页面
exit;
}
4.同步退出。
同步退出比较简单,使用 uc_user_synlogout()获取同步退出代码,然后输出到浏览器。
$ucsynlogout = uc_user_synlogout();
echo $ucsynlogout;
注意:所有用到uc api函数的地方都应该确定是否导入了uc_client/client.php文件,api函数都封装在这里面,以及UC配置文件。
require_once ‘./config.inc.php’;
require_once ‘./uc_client/client.php’;
话说到这一步,就基本上实现了同步登陆和退出,至于为什么要激活这一步,需不需要激活,都是跟具体的项目相关的东西。此文不讨论这个。如果是新手整 合UC,这其他肯定会遇到一系列的问题,面对这样问题,我个人的建议是,学会调试!因为UC是异步通知应用,所以要想看到是否执行了某一个操作,最好用文 件日志来记录,比如:
function synlogout($get, $post) {
if(!API_SYNLOGOUT) {
return API_RETURN_FORBIDDEN;
}
//note 同步登出 API 接口
header(‘P3P: CP=”CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR”‘);
$f = fopen(“../log.txt”,”w+”); //文件记录下,是否通知到了本应用
fwrite($f,implode(“,”,$get));
}
此外,下载的ucenter压缩包里,除里有examples外,还有document,在遇到问题时,都可以阅读阅读。学会“学习”比任何技术都重要!