zoukankan      html  css  js  c++  java
  • 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
    ";
     89         $out .= "Accept: */*
    ";
     90         //$out .= "Referer: $boardurl
    ";
     91         $out .= "Accept-Language: zh-cn
    ";
     92         $out .= "Content-Type: application/x-www-form-urlencoded
    ";
     93         $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]
    ";
     94         $out .= "Host: $host
    ";
     95         $out .= 'Content-Length: '.strlen($post)."
    ";
     96         $out .= "Connection: Close
    ";
     97         $out .= "Cache-Control: no-cache
    ";
     98         $out .= "Cookie: $cookie
    
    ";
     99         $out .= $post;
    100     } else {
    101         $out = "GET $path HTTP/1.0
    ";
    102         $out .= "Accept: */*
    ";
    103         //$out .= "Referer: $boardurl
    ";
    104         $out .= "Accept-Language: zh-cn
    ";
    105         $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]
    ";
    106         $out .= "Host: $host
    ";
    107         $out .= "Connection: Close
    ";
    108         $out .= "Cookie: $cookie
    
    ";
    109     }
    110     $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
    111     if(!$fp) {
    112         return '';//note $errstr : $errno 
    
    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 == "
    " ||  $header == "
    ")) {
    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();
    }
    复制代码
  • 相关阅读:
    Centos 通过yum的方式升级内核
    docker入门——镜像简介
    docker入门——管理容器
    docker入门——安装及简单操作
    docker入门——简介
    Centos 6安装 Jenkins
    Centos 7 搭建OpenStack 私有云——(1)基础环境配置
    Python正则表达式
    多选控件multipicker
    绝对定位 软键盘弹出时顶起底部按钮
  • 原文地址:https://www.cnblogs.com/archoncap/p/4284148.html
Copyright © 2011-2022 走看看