架設discuz與ucenter應用同步登入筆記
Discuz!是個可免費下載的PHP網絡論壇程式,簡稱DZ,由戴志康(Crossday)所創立,目前最新版本是X2.5。[2] 前身為Crossday Bulletin(CDB),最初改自XMB,爾後改寫成為現今的Discuz!社群論壇程式,由康盛創想所有。現在Discuz!已成為大中華地區最多用戶使用的論壇程序。
Discuz!的原始碼可免費下載,但它并不是開源軟件,因為其許可證不符合開放原始碼的定義。from wiki
discuz論壇的架設只要參照官方論壇的說明就沒有問題了,這裡將著重在第三方php網站整合ucenter。ucenter在與其他php應用整合上的流程與架構示意圖大概如下圖:
在所有ucenter的應用中,都是透過uc.php這個檔案來做listening,再根據指示做相對應的動作(如:登入、登出等)。流程大概是,假設ucenter共有A, B這兩個應用,當A透過client.php發出同步登入成功指示給ucenter,接著uc service再去發出登入的指示給下面所有應用(A, B),透過呼叫每個應用的uc.php,帶入相對應動作的get參數。
一開始先去此處下載ucenter的source code,我們需要裡面的advanced資料夾,解壓縮後將examples內的所有檔案與資料夾,還有uc_client資料夾,複製至自己的應用目錄下,如下圖檔案結構
假設ucenter server已經架設完畢(筆者使用已整合ucenter的discuz版本),第一個動作便是要註冊欲整合的應用至ucenter內,如下圖
完成應用的註冊後,回到應用管理的頁面,確認第三方應用是否通信成功(最主要即是能連到第三方應用的api/uc.php這個檔案),如下圖
通信成功剩下的就是針對登入、登出、註冊等做相對應的動作,這裡我的情境是有ucenter, discuz跟第三方應用,即ucenter搭配兩個應用。需求是當第三方應用登入時,要一併新增帳號並登入至discuz論壇內(透過ucenter同步登入功能),而這裡安裝的是已整合ucenter的discuz論壇,所以處理上比較單純,只要專注在修改discuz內api/uc.php這個檔案,並且另外寫個登入介接的php檔案連結即可。
有幾個ucenter的函式要稍微關心一下:
- uc_user_login: 使用者帳號與密碼登入ucenter
- uc_authcode: 建立ucenter登入成功的cookie內容
- uc_user_synlogin: 發佈同步登入訊息給ucenter,通知其他應用也一併登入
- uc_user_register: 註冊帳號至ucenter
以上這幾個函式都在uc_client/client.php這檔案內,使用前include即可。
大致的流程為:interface.php(登入介接)確認第三方應用登入成功 -> 利用client.php內的函式同步登入到ucenter與其他應用內 -> ucenter service會同步發佈登入成功通知到各個應用內的uc.php -> 接著即呼叫相對應的函式設定cookie同步登入。
<?php
include './config/config_ucenter.php';
include './uc_client/client.php';
list($uid, $username, $password, $email) = uc_user_login($username, $password);
setcookie('Example_auth', '', -86400);
if($uid > 0) {
//用戶登陸成功,設置 Cookie,加密直接用 uc_authcode 函數,用戶使用自己的函數
setcookie('Example_auth', uc_authcode($uid."\t".$username, 'ENCODE'));
//生成同步登錄的代碼
$ucsynlogin = uc_user_synlogin($uid);
echo $ucsynlogin; // output the javascript code to sync login
} else {
// register to ucenter
$uid = uc_user_register($username, $password, "test@example.com");
if($uid <= 0) {
if($uid == -1) {
echo '用戶名不合法';
} elseif($uid == -2) {
echo '包含要允許註冊的詞語';
} elseif($uid == -3) {
echo '用戶名已經存在';
} elseif($uid == -4) {
echo 'Email 格式有誤';
} elseif($uid == -5) {
echo 'Email 不允許註冊';
} elseif($uid == -6) {
echo '該 Email 已經被註冊';
} else {
echo '未定義';
}
} else {
//註冊成功,設置 Cookie,加密直接用 uc_authcode 函數,用戶使用自己的函數
setcookie('Example_auth', uc_authcode($uid."\t".$username, 'ENCODE'));
$ucsynlogin = uc_user_synlogin($uid);
echo $ucsynlogin; // output the javascript code
}
}
?>
sync是根據ucenter的account,若該username沒在ucenter內要先註冊再發佈同步登入訊息(注意username最少3個字元)。當ucenter登入成功並發佈同步訊息後,會呼叫每個應用api/uc.php的synlogin函式。在這需要針對discuz沒有此帳號即註冊至資料庫內並登入的動作。
<?php
function synlogin($get, $post) {
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"');
$cookietime = 31536000;
$uid = intval($get['uid']);
if(($member = getuserbyuid($uid, 1))) {
dsetcookie('auth', authcode("$member[password]\t$member[uid]", 'ENCODE'), $cookietime);
} else { //非激活狀態下寫入
$query = DB::query("SELECT email FROM ".DB::table('ucenter_members')." WHERE uid='$uid'");
if($a = DB::fetch($query)){
$email = $a['emaiil'];
}else{
$email = '';
}
$userdata = array(
'uid' => $get['uid'],
'username' => $get['username'],
'password' => $get['password'],
'email' => $email,
'adminid' => 0,
'groupid' => 10,
'regdate' => $get['time'],
'credits' => 0,
'timeoffset' => 9999
);
$tmp = DB::insert('common_member', $userdata);
$tmp = DB::insert('common_member_count', array('uid'=>$get['uid']));
dsetcookie('auth', authcode("$get[password]\t$get[uid]", 'ENCODE'), $cookietime);
}
}
?>
done.