以用户登录为例介绍,其它注销,改密码,消息,头像,好友均类同。

  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();
}

uc_client是如何与UCenter进行通信的的更多相关文章

  1. Flutter学习笔记(29)--Flutter如何与native进行通信

    如需转载,请注明出处:Flutter学习笔记(29)--Flutter如何与native进行通信 前言:在我们开发Flutter项目的时候,难免会遇到需要调用native api或者是其他的情况,这时 ...

  2. ucenter 显示通信成功的条件

    应用的主 URL+/api/uc.php?code= 如果这个页面返回1,则通信成功,也就是说,uc.php是通信成功里重要的一环 事实上,我还没有通信成功,我只是写了一个1在欺骗服务端

  3. .net mvc通过ucenter和 discuz的整合,nopcommerce ucenter 插件的方式实现

    discuz无疑是目前市面上最好的论坛之一,对于大多数公司来说,用discuz搭建一个论坛肯定是最节约成本的选择,然而我们的会员想要和discuz进行整合的话,只有两种荀泽,一种直接选用discuz的 ...

  4. ucenter无法双向同步setting[allowsynlogin]为0问题解决

    深入探索ucenter各种通信失败问题飞狐ITWeb问题描述:A,B两个应用,A的登录操作等同步到B,而B无法同步到A,即只能从A单向同步到B,AB之间没有实现双向同步以前碰到过没记录,这次记录下来查 ...

  5. Asp.net 与 UCenter 用户同步之实施过程

    在写这篇文章的时候,我还在想,这篇文章也许能给你带来一些收获,但或许会令你更加的迷茫,为什么会这样?因为:1.UCenter虽然足够强大,但正为它的强大,它的不少暗箱操作使得我们望而生畏,我们不害怕出 ...

  6. UCenter在JAVA项目中实现的单点登录应用实例

    Comsenz(康盛)的UCenter当前在国内的单点登录领域占据绝对份额,其完整的产品线令UCenter成为了账号集成方面事实上的标准. 基于UCenter,可以将Comsenz旗下的Discuz! ...

  7. 一步一步学Silverlight 2系列(15):数据与通信之ASMX

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  8. 一步一步学Silverlight 2系列(14):数据与通信之WCF

    一步一步学Silverlight 2系列(14):数据与通信之WCF   概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框 ...

  9. 谈谈Nginx和php之间是交互与通信的方式

    Nginx是俄国人最早开发的Webserver,现在已经风靡全球,相信大家并不陌生.PHP也通过二十多年的发展来到了7系列版本,更加关注性能.这对搭档在最近这些年,叱咤风云,基本上LNMP成了当下的标 ...

随机推荐

  1. 【Javascript】—— 1 方法function的高级特性

    本篇仅仅对于function作简单的讲解,在javascript中function不仅仅是方法,它其实是一个变量,因此拥有自己的属性,并且可以当做参数传递给其他的方法. 那么传统的方法,按照java的 ...

  2. Bata版本冲刺计划及安排

    下一阶段需要改进完善的功能 UI: 1. 界面不够精细,布局不够美观并且尚有BUG没有解决,图形.色彩间不够协调. 2. 理清界面间的跳转逻辑. 搜索: 搜索成功并定位后,不会影响地理标签的显示. 定 ...

  3. Mvc多级Views目录 asp.net mvc4 路由重写及 修改view 的寻找视图的规则

    一般我们在mvc开发过程中,都会碰到这样的问题.页面总是写在Views文件夹下,而且还只能一个Controller的页面只能写在相应的以 Controller名命名的文件夹下.如果我们写到别处呢?那么 ...

  4. Java设计模式-工厂方法模式(Factory Method)

    工厂方法模式(Factory Method) 工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建.在以下的三种模式中,第一种如果传入的字符串有误,不能正确创 ...

  5. 【HDU 5578】Friendship of Frog

    题 题意 求相同字母最近距离 分析 用数组保存各个字母最后出现的位置,维护最小距离. 代码 #include <cstdio> int c[30],n,p,a,minl; char ch; ...

  6. yii2URL美化

    yii2的url 域名/index.php?r=site%2Findex 实际为 域名/index.php?r=site/index 可以美化下 可以在main.php中配置 'components' ...

  7. 宿主机( win 7 系统) ping 虚拟机VMware( cent os 6.6 ) 出现“请求超时”或者“无法访问目标主机”的解决方法

    首先虚拟机的网络连接设置为"Host-only": 然后在 cmd 窗口中查看 VMnet1 的 ip 地址,这里是 192.168.254.1 接下来在 Linux 中设置网卡地 ...

  8. Codeforces 295A Greg and Array

    传送门 A. Greg and Array time limit per test 1.5 seconds memory limit per test 256 megabytes input stan ...

  9. Selenium2+python自动化13-Alert

    不是所有的弹出框都叫alert,在使用alert方法前,先要识别出它到底是不是alert.先认清楚alert长什么样子,下次碰到了,就可以用对应方法解决.alert\confirm\prompt弹出框 ...

  10. IOS基础之 (十) 内存管理

    一 基本原理 1.什么是内存管理 移动设备的内存有限,每个app所能占用的内存是有限制的. 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间.比如回收一些不需要使用 ...