uc_client是如何與UCenter進行通信的


以用戶登錄為例介紹,其它注銷,改密碼,消息,頭像,好友均類同。

  1. 從用戶xxx在某一應用程序的login.php,輸入用戶名,密碼講起。先用uc_user_login函數到uc_server驗證此用戶和密碼,如正確,則寫入session,寫入cookies,並更新應用程序會員表中的登錄ip,登錄時間。用戶感覺不到這個過程。
  2. 然后通過uc_user_synlogin通知uc_server 用戶xxx登錄成功,這個過程可能使用ajax,用戶感覺不到通知過程。
  3. uc_server收到這個消息后,馬上命令手下,把xxx登錄的消息,像令牌環一樣,發給所有願意接收(后台中那個是否開啟同步登錄)這個消息的其它應用程序。其實就是帶參數訪問一下各應用程序的uc.php,用戶感覺不到這個過程。
  4. 各應用程序靠api下的uc.php來接收uc_server發來的消息,並對uc_server言聽計從,讓干什么就干什么。現在,收到讓xxx用戶在你的程序中登錄的命令,馬上執行。並寫本應用程序的session,並且使用p3p,寫入相同域或不同域的cookies.   用戶感覺不到這個過程。
  5. 最后所有和uc整合的程序,xxx均登錄成功。用戶從www.test.com/bbs登錄后, 跳到www.test.com/news同樣顯示登錄。因為bbs 和news系統在后台均已登錄。
  6. 應用程序與uc server的會話結束。

得益於uc設計的精巧過程,整個過程,用戶完全感覺不到ucenter的存在。這是整合程序歷史上的創新。

以下為Supesite的uc_client和ucenter登錄通信過程的一個例子:

1、登錄入口index.php?action=login

//系統頻道
if($_SGET['action'] != 'index') {     
    if(empty($channels['menus'][$_SGET['action']]['upnameid']) && $channels['menus'][$_SGET['action']]['upnameid'] != 'news') {
        $scriptfile = S_ROOT.'./'.$_SGET['action'].'.php';
    } else {
        $scriptfile = S_ROOT.'./news.php';
    }
    //echo   $scriptfile;
    if(file_exists($scriptfile)) {
        include_once($scriptfile);
        exit();
    }
}

提交登錄action:batch.login.php?action=login

2、登錄處理地址batch.login.php?action=login

include_once(S_ROOT.'./uc_client/client.php');

// 登錄操作及其中涉及到的一些函數:
$password = $_POST['password'];
$username = $_POST['username'];
// 去ucenter進行遠程登錄驗證
$ucresult = uc_user_login($username, $password, $loginfield == 'uid');

如果登錄成功,則查本地用戶信息。如果有更新本地信息,如果沒有插入新的用戶數據保持與ucenter進行同步。

然后同步其他子系統登錄信息:

$msg = $lang['login_succeed'].uc_user_synlogin($members['uid']);

function uc_user_synlogin($uid) {
    $uid = intval($uid);
    $return = uc_api_post('user', 'synlogin', array('uid'=>$uid));
    return $return;
}

下面是一些程序代碼與注釋:

  1 /**
  2  *  dfopen 方式取指定的模塊和動作的數據
  3  *
  4  * @param string $module    請求的模塊
  5  * @param string $action     請求的動作
  6  * @param array $arg        參數(會加密的方式傳送)
  7  * @return string
  8  */
  9 function uc_api_post($module, $action, $arg = array()) {
 10     $s = $sep = '';
 11     foreach($arg as $k => $v) {
 12         $k = urlencode($k);
 13         if(is_array($v)) {
 14             $s2 = $sep2 = '';
 15             foreach($v as $k2 => $v2) {
 16                 $k2 = urlencode($k2);
 17                 $s2 .= "$sep2{$k}[$k2]=".urlencode(uc_stripslashes($v2));
 18                 $sep2 = '&';
 19             }
 20             $s .= $sep.$s2;
 21         } else {
 22             $s .= "$sep$k=".urlencode(uc_stripslashes($v));
 23         }
 24         $sep = '&';
 25     }
 26     $postdata = uc_api_requestdata($module, $action, $s);
 27     
 28     return uc_fopen2(UC_API.'/index.php', 500000, $postdata, '', TRUE, UC_IP, 20);
 29 }
 30 
 31 /**
 32  * 構造發送給用戶中心的請求數據
 33  *
 34  * @param string $module    請求的模塊
 35  * @param string $action    請求的動作
 36  * @param string $arg        參數(會加密的方式傳送)
 37  * @param string $extra        附加參數(傳送時不加密)
 38  * @return string
 39  */
 40 function uc_api_requestdata($module, $action, $arg='', $extra='') {
 41     $input = uc_api_input($arg);
 42     $post = "m=$module&a=$action&inajax=2&release=".UC_CLIENT_RELEASE."&input=$input&appid=".UC_APPID.$extra;
 43     return $post;
 44 }
 45 
 46 function uc_api_url($module, $action, $arg='', $extra='') {
 47     $url = UC_API.'/index.php?'.uc_api_requestdata($module, $action, $arg, $extra);
 48     return $url;
 49 }
 50 
 51 function uc_api_input($data) {
 52     $s = urlencode(uc_authcode($data.'&agent='.md5($_SERVER['HTTP_USER_AGENT'])."&time=".time(), 'ENCODE', UC_KEY));
 53     return $s;
 54 }
 55 
 56 /**
 57  *  遠程打開URL
 58  *  @param string $url        打開的url, 如 http://www.baidu.com/123.htm
 59  *  @param int $limit        取返回的數據的長度
 60  *  @param string $post        要發送的 POST 數據,如uid=1&password=1234
 61  *  @param string $cookie    要模擬的 COOKIE 數據,如uid=123&auth=a2323sd2323
 62  *  @param bool $bysocket    TRUE/FALSE 是否通過SOCKET打開
 63  *  @param string $ip        IP地址
 64  *  @param int $timeout        連接超時時間
 65  *  @param bool $block        是否為阻塞模式
 66  *  @return            取到的字符串
 67  */
 68 function uc_fopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) {
 69     $__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1;
 70     if($__times__ > 2) {
 71         return '';
 72     }
 73     $url .= (strpos($url, '?') === FALSE ? '?' : '&')."__times__=$__times__";
 74     return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block);
 75 }
 76 
 77 function uc_fopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) {
 78     $return = '';
 79     $matches = parse_url($url);
 80     !isset($matches['host']) && $matches['host'] = '';
 81     !isset($matches['path']) && $matches['path'] = '';
 82     !isset($matches['query']) && $matches['query'] = '';
 83     !isset($matches['port']) && $matches['port'] = '';
 84     $host = $matches['host'];
 85     $path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
 86     $port = !empty($matches['port']) ? $matches['port'] : 80;
 87     if($post) {
 88         $out = "POST $path HTTP/1.0\r\n";
 89         $out .= "Accept: */*\r\n";
 90         //$out .= "Referer: $boardurl\r\n";
 91         $out .= "Accept-Language: zh-cn\r\n";
 92         $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
 93         $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
 94         $out .= "Host: $host\r\n";
 95         $out .= 'Content-Length: '.strlen($post)."\r\n";
 96         $out .= "Connection: Close\r\n";
 97         $out .= "Cache-Control: no-cache\r\n";
 98         $out .= "Cookie: $cookie\r\n\r\n";
 99         $out .= $post;
100     } else {
101         $out = "GET $path HTTP/1.0\r\n";
102         $out .= "Accept: */*\r\n";
103         //$out .= "Referer: $boardurl\r\n";
104         $out .= "Accept-Language: zh-cn\r\n";
105         $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
106         $out .= "Host: $host\r\n";
107         $out .= "Connection: Close\r\n";
108         $out .= "Cookie: $cookie\r\n\r\n";
109     }
110     $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
111     if(!$fp) {
112         return '';//note $errstr : $errno \r\n
113     } else {
114         stream_set_blocking($fp, $block);
115         stream_set_timeout($fp, $timeout);
116         @fwrite($fp, $out);
117         $status = stream_get_meta_data($fp);
118         if(!$status['timed_out']) {
119             while (!feof($fp)) {
120                 if(($header = @fgets($fp)) && ($header == "\r\n" ||  $header == "\n")) {
121                     break;
122                 }
123             }
124 
125             $stop = false;
126             while(!feof($fp) && !$stop) {
127                 $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
128                 $return .= $data;
129                 if($limit) {
130                     $limit -= strlen($data);
131                     $stop = $limit <= 0;
132                 }
133             }
134         }
135         @fclose($fp);
136         return $return;
137     }
138 }

遠程同步登錄子系統操作之后:

//顯示信息
function showmessage($message, $url_forward='', $second=3, $vars=array()) {
    global $_SGLOBAL, $_SCONFIG, $_SC, $channels;

    if(empty($_SGLOBAL['inajax']) && $url_forward && empty($second)) {
        //直接301跳轉
        obclean();
        header("HTTP/1.1 301 Moved Permanently");
        header("Location: $url_forward");
    } else {
        if(!defined('IN_SUPESITE_ADMINCP')) {
            $tpl_file = 'showmessage';
            $fullpath = 0;
            include_once(S_ROOT.'./language/message.lang.php');
            if(!empty($mlang[$message])) $message = $mlang[$message];
        } else {
            $tpl_file = 'admin/tpl/showmessage.htm';
            $fullpath = 1;
            include_once(S_ROOT.'./language/admincp_message.lang.php');
            if(!empty($amlang[$message])) $message = $amlang[$message];
        }

        if(isset($_SGLOBAL['mlang'][$message])) $message = $_SGLOBAL['mlang'][$message];
        foreach ($vars as $key => $val) {
            $message = str_replace('{'.$key.'}', $val, $message);
        }
        //顯示
        obclean();
        if(!empty($url_forward)) {
            $second = $second * 1000;
            $message .= "<script>setTimeout(\"window.location.href ='$url_forward';\", $second);</script><ajaxok>";
        }

        include template($tpl_file, $fullpath);
        ob_out();
    }
    exit();
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM