测试使用程序:UCenter_1.6.0_SC_UTF8、Discuz! X2、MLECMS
先装好discuz和ucenter安装方法已经众所皆知了,这里不在重复说明。
安装好后,登录ucenter,添加 一个mlecms的应用,如下图:
下面我们一步步来操作:
第一步:打开下载UCenter_1.6.0_SC_UTF8文件夹中的advanced文件夹,这是和其它网站的接口文件,里面的document就是接口的API说明,examples文件夹就是一些使用例子,也可以根椐这些例子参照使用,uc_client是接口文件。
第二步:把examples文件夹中复制include文件夹和api文件夹到你网站根目录,include文件夹内包含一个文件叫db_mysql.class.php,这是连接数据库的类。
第三步:将uc_client文件夹整个复制到你网站根目录,uc_client之前说了是接口代码,现在根目录已经有api、include和uc_client三个文件夹了。
第四步:复制examples文件夹内的config.inc.php到你网站的根目录,这是配置UCenter的配置文件
第五步:配置config.inc.php的各种参数把mlecms的应用里“应用的 UCenter 配置信息”下文本框里的内容复制到 config.inc.php中,如下图:
照上面步骤配置好后,您的应用程序应该可以和ucenter通信成功了,如下图:
下面我们就来对mlecms的登录、登出、和注册页面进行一些修改,来达到与discuz同步的目的。
你需要一本ucenter接口开发手册,方便你顺利的实现下面的步骤。下载地址:ucenter接口开发手册
(1)我们先来实现双向同步登录,也就是用户在mlecms里登录,转到discuz里也是登录状态,反过来也一样。
首先在mlecms登录文件里,加入同步登录的代码,我们找到mlecms的登录页面member/login.php:
(注意:要使用uc的同步接口函数,先要引用:config.inc.php和uc_client/client.php这两个文件)
if(!empty($_POST['username']) && !empty($_POST['password'])){
$captcha = true;
if($mle['login_captcha']){
$img = new captcha();
$captcha = $img->check($_POST['captcha']);
}
if($captcha === true){
$flag = member::login($_POST['username'],$_POST['password'],numeric($expire));
switch($flag){
case 0 : msgbox($language['page']['not_exist'],$config['url'].misc::url('login')); break;
case -1 : msgbox($language['page']['password_error'],$config['url'].misc::url('login')); break;
case -2 : msgbox($language['page']['mail_activation'],$config['url'].misc::url('login')); break;
case -3 : msgbox($language['page']['manage_activation'],$config['url'].misc::url('login')); break;
case -4 : msgbox($language['page']['refused_login'],$config['url'].misc::url('login')); break;
case -5 : msgbox($language['page']['unknown_error'],$config['url'].misc::url('login')); break;
default :
msgbox('',$config['url'].'member/');
break;
}
} else {
msgbox($language['page']['captcha_error'],$config['url'].misc::url('login'));
}
}
根据 ucenter接口开发手册和 UCenter_1.6.0_SC_UTF8文件夹里login_db.php例子,添加了同步登录的代码,如下:
if(!empty($_POST['username']) && !empty($_POST['password'])){
$captcha = true;
if($mle['login_captcha']){
$img = new captcha();
$captcha = $img->check($_POST['captcha']);
}
if($captcha === true){
$flag = member::login($_POST['username'],$_POST['password'],numeric($expire));
switch($flag){
case 0 : msgbox($language['page']['not_exist'],$config['url'].misc::url('login')); break;
case -1 : msgbox($language['page']['password_error'],$config['url'].misc::url('login')); break;
case -2 : msgbox($language['page']['mail_activation'],$config['url'].misc::url('login')); break;
case -3 : msgbox($language['page']['manage_activation'],$config['url'].misc::url('login')); break;
case -4 : msgbox($language['page']['refused_login'],$config['url'].misc::url('login')); break;
case -5 : msgbox($language['page']['unknown_error'],$config['url'].misc::url('login')); break;
default :
//通过接口判断登录帐号的正确性,返回值为数组
list($uid, $username, $password, $email) = uc_user_login($_POST['username'], $_POST['password']);
setcookie('auth', '', -86400);
if($uid > 0) {
/* if(!$db->result_first("SELECT count(*) FROM {$tablepre}members WHERE uid='$uid'")) {
//判断用户是否存在于用户表,不存在则跳转到激活页面
$auth = rawurlencode(uc_authcode("$username\t".time(), 'ENCODE'));
echo '您需要需要激活该帐号,才能进入本应用程序<br><a href="'.$_SERVER['PHP_SELF'].'?example=register&action=activation&auth='.$auth.'">继续</a>';
exit;
} */
//用户登陆成功,设置 Cookie,加密直接用 uc_authcode 函数,用户使用自己的函数
setcookie('auth', uc_authcode($uid."\t".$username, 'ENCODE'));
//生成同步登录的代码
$ucsynlogin = uc_user_synlogin($uid);
echo '登录成功'.$ucsynlogin.'<br><a href="'.$_SERVER['PHP_SELF'].'">继续</a>';
msgbox('',$config['url'].'member/');
} elseif($uid == -1) {
msgbox( '用户不存在,或者被删除',$config['url'].misc::url('login'));
} elseif($uid == -2) {
msgbox( '密码错',$config['url'].misc::url('login'));
} else {
msgbox( '未定义',$config['url'].misc::url('login'));
}
break;
}
} else {
msgbox($language['page']['captcha_error'],$config['url'].misc::url('login'));
}
}
测试:在discuz里注册一个用户名为test的用户,因为discuz与ucenter里的同步已经写好的,ucenter里也会有这个用户,在mlecms里也注册一个用户名为test的用户,然后我们在mlecms里用这个用户登录,成功;转到discuz页面,用户也是登录状态。
下面修改mlecms的api/uc.php文件,修改synlogin 函数,加入同步登录代码:
function synlogin($get, $post) {
$uid = $get['uid'];
$username = $get['username'];
//$pwd = $get['password'];
global $_G;
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"');
header("Location:../member/login.php?username=$username&uid=$uid");//同步登录
}
修改mlecms/inc/class/member.class.php,新增加一个synclogin函数,来使用用户名和用户id实现登录:
public static function synclogin($username,$uid,$expire = 0){
global $db,$gmt_time;
$username = trim(preg_replace('/[\'\"\\\\\/]/','',$username));
$uid = trim(preg_replace('/[\'\"\\\\\/]/','',$uid));
$row = $db->query("SELECT a.*,b.`rankname` FROM `{$db->prefix}members` a,`{$db->prefix}rank` b WHERE (a.`username` = '{$username}' || a.`email` = '{$username}') && a.`level` = b.`id` && a.`id` = '{$uid}' LIMIT 1",1);
if(isset($row['username'])){
//if(md5(md5($password).md5($row['encryption'])) == $row['password']){
if($row['audit'] == 0 && $row['effective']){
$expire != 0 && $expire = $gmt_time + ($expire * 3600);
setcookie('mlecms_user_login',encryption('mlecms','ENCOD',WEBKEY),$expire,'/');
setcookie('mlecms_user_id',encryption($row['id'],'ENCOD',WEBKEY),$expire,'/');
setcookie('mlecms_user_auth',encryption($row['id'].$row['password'].$row['encryption'],'ENCOD',WEBKEY),$expire,'/');
setcookie('mlecms_user_name',$row['username'],$expire,'/');
setcookie('mlecms_user_email',$row['email'],$expire,'/');
setcookie('mlecms_user_frequency',$row['frequency'] + 1,$expire,'/');
$rankname = explode(',',$row['rankname']);
$rankname = $rankname[LANG - 1];
setcookie('mlecms_user_rankname',$rankname ,$expire,'/');
setcookie('mlecms_user_money',$row['money'],$expire,'/');
setcookie('mlecms_user_usemoney',$row['usemoney'],$expire,'/');
setcookie('mlecms_user_scores',$row['scores'],$expire,'/');
$ip = explode(',',$row['loginip']);
$ip = $ip[1].','.get_ip();
$tm = explode(',',$row['logintime']);
$last_time = is_numeric($tm[1]) ? $tm[1] : numeric($tm[0]);
$tm = $tm[1].','.$gmt_time;
$integral = numeric($row['scores']);
if($last_time && $last_time < ($gmt_time - 43200)){
$member_config = self::get_config();
$integral += $member_config['login_scores'];
}
$level = self::get_upgrade_rank($row['level'],$integral,$row['money']);
$db->execute("UPDATE `{$db->prefix}members` SET `loginip` = '{$ip}',`logintime` = '{$tm}',`frequency` = (`frequency`+1),`scores` = '{$integral}',`level` = '{$level}' WHERE `id` = '{$row['id']}';");
return is_numeric($row['id']) ? $row['id'] : -5;
} elseif ($row['audit'] == 1){
return -2;
} elseif ($row['audit'] == 2){
return -3;
} elseif ($row['effective'] == 0){
return -4;
} else {
return -5;
}
//} else {
// return -1;
//}
} else {
return 0;
}
}
下面需要修改 member/login.php页面,加入使用get方式登录的代码:
if(!empty($_GET['username'])&&!empty($_GET['uid']))
{
$syn_flag = member::synclogin($_GET['username'],$_GET['uid'],numeric($expire));
switch($syn_flag){
case 0 : msgbox($language['page']['not_exist'],$config['url'].misc::url('login')); break;
case -1 : msgbox($language['page']['password_error'],$config['url'].misc::url('login')); break;
case -2 : msgbox($language['page']['mail_activation'],$config['url'].misc::url('login')); break;
case -3 : msgbox($language['page']['manage_activation'],$config['url'].misc::url('login')); break;
case -4 : msgbox($language['page']['refused_login'],$config['url'].misc::url('login')); break;
case -5 : msgbox($language['page']['unknown_error'],$config['url'].misc::url('login')); break;
default : msgbox('',$config['url'].'member/'); break;
}
}
测试:使用test用户在discuz登录,转到mlecms页面,用户也为登录状态,同步成功。
(注意:要使这一步顺利实现,需要到discuz后台->界面->界面设置->全局 里把登录和注册的浮动窗口的勾去掉,因为没去掉这个勾的原因我一上午没成功,大家不要在走弯路喽)
至此,双向同步登录已经基本实现。
(2)实现双向同步登出,也就是用户在mlecms里登出,转到论坛也是登出状态。
mlecms里的login.php的登录代码:
$action == 'logout' && member::logout() && msgbox('',$config['url']);
加入同步登出代码:
if($action == 'logout' && member::logout())
{
echo uc_user_synlogout(); //同步退出
msgbox('',$config['url']);
}
测试:在mlecms使用户退出登录,转到discuz页面,用户也为登出状态,同步登出成功。
下一步,修改api/uc.php里的synlogout函数,加入登出代码:
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"');
header("Location:../member/login.php?action=logout");//同步登出
}
测试:在discuz使test用户退出登录,转到mlecms页面,用户也为登出状态,同步登出成功。
第一部分先写到这里,要不太长了不好看~