依附於Discuz UCenter的子應用都會有一個選項:
意思很明白了,那它是如何實現的呢?
UC/Control/user.PHP中有一個onsynlogin方法,這裡就是處理同步登錄的。
function onsynlogin() {
$this->init_input();
$uid = $this->input('uid');
if($this->app['synlogin']) {
if($this->user = $_ENV['user']->get_user_by_uid($uid)) {
$synstr = '';
foreach($this->cache['aPPS'] as $appid => $app) {
if($app['synlogin'] && $app['appid'] != $this->app['appid']) {
$synstr .= '<script type="text/Javascript" src="'.$app['url'].'/api/uc.PHP?time='.$this->time.'&code='.urlencode($this->authcode('action=synlogin&username='.$this->user['username'].'&uid='.$this->user['uid'].'&password='.$this->user['passWord']."&time=".$this->time, 'ENCODE', $app['authkey'])).'" reload="1"></script>';
}
}
return $synstr;
}
}
return '';
}
當調用該方法時,實際上會去調用該應用下api/uc.PHP文件,將用戶名、密碼及時間戳做為參數傳遞。
以上是實現的第一步。
第二步,當應用接收到UC的請求後,會調用uc_note類中的synlogin方法,該方法的核心是送一個P3P的HTTP頭,然後種下COOKIE。
$discuz_auth_key = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
$uid = intval($uid);
$query = $this->db->query("SELECT username, uid, passWord, secques FROM ".$this->tablepre."members WHERE uid='$uid'");
if($member = $this->db->fetch_array($query)) {
_setcookIE('sid', '', -86400 * 365);
_setcookie('cookietime', $cookIEtime, 31536000);
_setcookIE('auth', _authcode("$member[passWord]\t$member[secques]\t$member[uid]", 'ENCODE', $discuz_auth_key), $cookIEtime);
} else {
_setcookie('cookietime', $cookIEtime, 31536000);
_setcookie('loginuser', $username, $cookIEtime);
_setcookie('activationauth', _authcode($username, 'ENCODE', $discuz_auth_key), $cookIEtime);
}
對於Disucz這種基於COOKIE驗證的應用來說,就實現了同步登錄。