主站的登录判别是通过客户端的cookie的
还好,主域名是一样的,不然,通过的cookie实现同步登录估计就不行了
我用的是discuz X3
大概的思路逻辑是:
1、主站登录之后,用户去了论坛:
1、判断某个cookie 是否存在,比如is_login_key ,如果存在,则获取其值;
2、根据cookie值通过接口到主站获取此用户的信息;
3、查询discuz中是否存在此用户,如果存在,则获取其值,如果不存在则插入信息;
4、根据获取的值设置用户在discuz为登录状态;
主要更改的文件为./source/class/discuz/discuz_application.php:
public function init() {
if (!$this->initated) {
$this->_init_db();
$this->_init_setting();
$this->_init_user();
$this->_init_session();
$this->_init_mobile();
$this->_init_cron();
$this->_init_misc();
$this->_init_autologin();
}
$this->initated = true;
}
主要是 $this->_init_autologin();
他的实体方法是:
private function _init_autologin() {
if (!isset($_COOKIE['is_login_key'])) {
returnfalse;
}
if ($this->session->var['uid']) {
returnfalse;
}
require_onceDISCUZ_ROOT .'./source/function/my_func.php';
$userinfo = getMemberInfoByCookie();
if ($userinfo['status'] != 0) {
returnfalse;
}
if (empty($userinfo['username'])) {
$href=$d2AppendNickUrl;
showmessage(lang('member/template','nickempty'),$href);
}
global $_G;
$user = C::t('common_member')->fetch_by_username(addslashes($userinfo['username']));
//如果在discuz中不存在则插入
if (!count($user)) {
loaducenter();
$newusername= !empty($userinfo['username']) ?$userinfo['username'] : $userinfo['email'];
$newpassword='000000';
$newemail=$userinfo['email'];
$uid= uc_user_register(addslashes($newusername),$newpassword,$newemail);
loadcache('fields_register');
$init_arr=explode(',',$_G['setting']['initcredits']);
$password= md5(random(10));
C::t('common_member')->insert($uid,$newusername,$password,$newemail, $_G['clientip'], 10,$init_arr);
}
$result = array();
$res = count($user) ? $user: C::t('common_member')->fetch_by_username(addslashes($userinfo['username']));
if ($res) {
$result['ucresult'] =array(
'email'=>$res['email'],
'password'=>'000000',
'username'=>$res['username'],
'uid'=>$res['uid']
);
$result['member'] =$res;
$result['status'] = 1;
require_oncelibfile('function/member');
setloginstatus($result['member'], 2592000);
checkfollowfeed();
}
}
my_func.php 文件中定义了调用主站的一些接口。
2、用户注册
注册的思路比较简单了,将用户的信息获取之后,调用主站的注册接口,如果返回成功,则在调用获取用户信息的接口,当然返回的信息中包含了login_key的值
加在./source/class/class_member.php文件中的 on_register方法
$activation = array();
if (isset($_GET['activationauth']) &&$activationauth&&is_array($activationauth)) {
if ($activationauth[1] == FORMHASH && !($activation= uc_get_user($activationauth[0]))) {
showmessage('register_activation_invalid','member.php?mod=logging&action=login');
}
}
之后
require_once dirname(dirname(__FILE__)) .'/function/my_func.php';
$params= sprintf('email=%s&password=%s&cpassword=%s',$_GET['email'],$_GET['password'],$_GET['password2']);
$json= request(REGURL,$params);
$res = json_decode($json, true);
$status=$res['result']['status'];
if ($status == 1) {
$logininfo= checkHitMember($_GET['email'],$_GET['password']);
if($logininfo['retCode'] == 0) {
$usercookie=explode(',',$logininfo['mes']);
$skey=str_replace(array('"','['),'',$usercookie[0]);
setcookie('com.d2.SKEY',$skey, time() + 3600 * 2,'/','infiplay.ru');
$info= lang('member/template','success') .', '. lang('member/template','nickempty');
$href=$d2AppendNickUrl;
showmessage($info,$href,array(),array(
'showid'=>'succeedmessage',
'extrajs'=>'<script type="text/javascript">'.
'setTimeout("window.location.href =\''.$href. '\';", 3000);' .
'$(\'succeedmessage_href\').href = \''.$href. '\';' .
'$(\'main_message\').style.display = \'none\';'.
'$(\'main_succeed\').style.display = \'\';',
// '$(\'succeedlocation\').innerHTML = \'' . $info . '\';</script>' . $ucsynlogin,
'striptags'=> false,
'showdialog'=> true
)
);
}else{
showmessage(lang('member/template','get_userinfo_error'));
}
} elseif($status== -6 ||$status == -2) {
//注册失败,已经存在
showmessage(lang('member/template','account_exists'));
} elseif($status== -5) {
//两次密码不一致
showmessage(lang('member/template','password_error'));
} else{
showmessage(lang('member/template','register_fail'));
}
request 方法是发送post/get请求的,网上一堆
3、用户在论坛上登录:
这个逻辑也比较简单了,就是根据用户的信息到主站去查询,如果存在,返回用户的信息,根据用户的信息判断是否存在,不存在则插入discuz的表中,然后设置其为登录状态:
./source/class/class_member.php的on_login方法的
$_G['uid'] =$_G['member']['uid'] = 0;
$_G['username'] =$_G['member']['username'] =$_G['member']['password'] ='';
if (!$_GET['password'] || $_GET['password'] != addslashes($_GET['password'])) {
showmessage('profile_passwd_illegal');
}
之后
require_once dirname(dirname(__FILE__)) .'/function/my_func.php';
$userinfo= getHitMemberInfo($_GET['username'],$_GET['password']);
$logininfo= checkHitMember($_GET['username'],$_GET['password']);
if ($userinfo['status'] == 0 && $logininfo['retCode'] == 0) {
$usercookie=explode(',',$logininfo['mes']);
$skey=str_replace(array('"','['),'',$usercookie[0]);
setcookie('is_login_key',$skey, time() + 3600 * 2,'/','domain');
if(empty($userinfo['username'])) {
$info= lang('member/template','nickempty');
$href=$d2AppendNickUrl;
//可根据自己的情况提示
showmessage($info,$href,array(),array(
'showid'=>'succeedmessage',
'extrajs'=>'<script type="text/javascript">'.
'setTimeout("window.location.href =\''.$href. '\';", 3000);' .
'$(\'succeedmessage_href\').href = \''.$href. '\';' .
'$(\'main_message\').style.display = \'none\';'.
'$(\'main_succeed\').style.display = \'\';'.
'$(\'succeedlocation\').innerHTML = \''.$info. '\';</script>' . $ucsynlogin,
'striptags'=> false,
'showdialog'=> true
)
);
}
$user= C::t('common_member')->fetch_by_username(addslashes($userinfo['username']));
if(!count($user)) {
loaducenter();
$newusername=$userinfo['username'];
$newpassword=$_GET['password'];
$newemail=$_GET['username'];
$uid= uc_user_register(addslashes($newusername),$newpassword,$newemail);
$profile=$verifyarr= array();
loadcache('fields_register');
$init_arr=explode(',',$_G['setting']['initcredits']);
$password= md5(random(10));
C::t('common_member')->insert($uid,$newusername,$password,$newemail, $_G['clientip'], 10,$init_arr);
//updatecache('setting');
}
} else{
showmessage('login_password_invalid');
}
这样就基本上ok了