一、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&action=login&loginsubmit=yes&handlekey=login&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