Discuz x3 UCenter实现同步登录原理

一、Discuz x3 的登陆页面URL是:/member.php?mod=logging&action=login javascript

二、这个登陆页面,登陆提交的地址是:
<form method="post" autocomplete="off" name="login" id="loginform_LKsWY" class="cl" onsubmit="pwdclear = 1;ajaxpost('loginform_LKsWY', 'returnmessage_LKsWY', 'returnmessage_LKsWY', 'onerror');return false;" action="member.php?mod=logging&amp;action=login&amp;loginsubmit=yes&amp;handlekey=login&amp;loginhash=LKsWY" fwin="login"> php

在 /member.php 文件中,咱们能够看到对应的加载的mod文件:
require DISCUZ_ROOT.'./source/module/member/member_'.$mod.'.php'; html

在/source/module/member/member_logging 文件中,咱们看到下面代码:
$ctl_obj = new logging_ctl();
$ctl_obj->setting = $_G['setting'];
$method = 'on_'.$_GET['action'];
$ctl_obj->template = 'member/login';
$ctl_obj->$method(); java

这里的类 logging_ctl 来自 source/class/class_member.php 文件。
这个类的 function on_login() 方法就是登陆处理的方法。 ajax

其中 on_login() 方法中下面这一行就是判断DB中数据是否能匹配。也就是对username和password进行验证。
     $result = userlogin($_GET['username'], $_GET['password'], $_GET['questionid'], $_GET['answer'], $this->setting['autoidselect'] ? 'auto' : $_GET['loginfield'], $_G['clientip']);
这个函数的实如今 source/function/function_member.php 这个文件中。 api

 

三、若是验证成功,将调用位于uc_client下client.php文件中的函数uc_user_synlogin,
class_member.php中调用代码:
    $ucsynlogin = $this->setting['allowsynlogin'] ? uc_user_synlogin($_G['uid']) : ''; cookie

uc_client下client.php文件中,uc_user_synlogin($uid) 函数
调用 $return = uc_api_post('user', 'synlogin', array('uid'=>$uid)); socket

参考:http://bbs.phpchina.com/thread-112304-1-1.html函数

uc_api_post函数的做用是将将数据经过socket发送到ucenter。post

对应的代码在 client.php 文件中,代码以下:

function uc_api_post($module, $action, $arg = array()) {
    $s = $sep = '';
    foreach($arg as $k => $v) {
        $k = urlencode($k);
        if(is_array($v)) {
            $s2 = $sep2 = '';
            foreach($v as $k2 => $v2) {
                $k2 = urlencode($k2);
                $s2 .= "$sep2{$k}[$k2]=".urlencode(uc_stripslashes($v2));
                $sep2 = '&';
            }
            $s .= $sep.$s2;
        } else {
            $s .= "$sep$k=".urlencode(uc_stripslashes($v));
        }
        $sep = '&';
    }
    $postdata = uc_api_requestdata($module, $action, $s);
    return uc_fopen2(UC_API.'/index.php', 500000, $postdata, '', TRUE, UC_IP, 20);
}

注意是向:UC_API.'/index.php' 这个地址, 通常是 /uc_server/index.php 这个文件。

四、而后这个函数后向Ucenter的index.php传递数据,index.php接受传递的数据,得到model为user,action为synlogin的值。

五、而后Ucenter的index.php调用/uc_server/control目录下的user.php类中的onsynlogin方法,

/uc_server/index.php  代码中以下代码:

define('UC_ROOT', dirname(__FILE__).'/');
include UC_ROOT."control/$m.php";
$method = 'on'.$a;

经过foreach循环,以javascript的方式通知uc应用列表中开启同步登录的应用进行同步登陆;即经过get方式传递给各个应用目录中api下的uc.php一些数据。

六、uc.php接收通知并处理get过来的数据,并在函数synlogin(位于uc.php中)经过函数_authcode加密数据(默认以UC_KEY做为密钥),用函数_setcookie设置cookie。

七、各个应用用对应的密钥解码上面设置的cookie,获得用户id等数据;经过这个值来判断用户是否通过其它应用登陆过,从而让用户能够自动登录。

应用程序的logging.php ------>uc_client中的client.php------>Ucenter------>应用程序中api/uc.php

其实Ucenter实现同步登录的原理就是cookie,一个应用登录成功以后,向Ucenter传递数据,让Ucenter通知其余的应用也设置cookie,这样用户在访问其余应用的时候经过已经设置好的cookie实现自动登录。了解了Ucenter的同步原理,再遇到没法同步登录,或者开发一些与UCenter接口的时候就会容易不少。

 

 

参考资料:

ucenter单点登录总结
http://xuebingnanmm.iteye.com/blog/681695

我的对UCenter通讯原理的总结
http://bbs.phpchina.com/thread-112304-1-1.html

无需激活直接同步登入discuz,php代码(直接可用)
http://www.discuz.net/thread-3495435-1-1.html

UCenter实现同步登录原理
http://xuqin.blog.51cto.com/5183168/1293551

[已解决] 修改文件实现Discuz新注册账号同步其余应用
http://www.discuz.net/forum.php?mod=viewthread&tid=3522745