uc_client是如何与UCenter进行通信的
以用户登录为例介绍,其它注销,改密码,消息,头像,好友均类同。
- 从用户xxx在某一应用程序的login.php,输入用户名,密码讲起。先用uc_user_login函数到uc_server验证此用户和密码,如正确,则写入session,写入cookies,并更新应用程序会员表中的登录ip,登录时间。用户感觉不到这个过程。
- 然后通过uc_user_synlogin通知uc_server 用户xxx登录成功,这个过程可能使用ajax,用户感觉不到通知过程。
- uc_server收到这个消息后,马上命令手下,把xxx登录的消息,像令牌环一样,发给所有愿意接收(后台中那个是否开启同步登录)这个消息的其它应用程序。其实就是带参数访问一下各应用程序的uc.php,用户感觉不到这个过程。
- 各应用程序靠api下的uc.php来接收uc_server发来的消息,并对uc_server言听计从,让干什么就干什么。现在,收到让xxx用户在你的程序中登录的命令,马上执行。并写本应用程序的session,并且使用p3p,写入相同域或不同域的cookies. 用户感觉不到这个过程。
- 最后所有和uc整合的程序,xxx均登录成功。用户从www.test.com/bbs登录后, 跳到www.test.com/news同样显示登录。因为bbs 和news系统在后台均已登录。
- 应用程序与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进行通信的的更多相关文章
- Flutter学习笔记(29)--Flutter如何与native进行通信
如需转载,请注明出处:Flutter学习笔记(29)--Flutter如何与native进行通信 前言:在我们开发Flutter项目的时候,难免会遇到需要调用native api或者是其他的情况,这时 ...
- ucenter 显示通信成功的条件
应用的主 URL+/api/uc.php?code= 如果这个页面返回1,则通信成功,也就是说,uc.php是通信成功里重要的一环 事实上,我还没有通信成功,我只是写了一个1在欺骗服务端
- .net mvc通过ucenter和 discuz的整合,nopcommerce ucenter 插件的方式实现
discuz无疑是目前市面上最好的论坛之一,对于大多数公司来说,用discuz搭建一个论坛肯定是最节约成本的选择,然而我们的会员想要和discuz进行整合的话,只有两种荀泽,一种直接选用discuz的 ...
- ucenter无法双向同步setting[allowsynlogin]为0问题解决
深入探索ucenter各种通信失败问题飞狐ITWeb问题描述:A,B两个应用,A的登录操作等同步到B,而B无法同步到A,即只能从A单向同步到B,AB之间没有实现双向同步以前碰到过没记录,这次记录下来查 ...
- Asp.net 与 UCenter 用户同步之实施过程
在写这篇文章的时候,我还在想,这篇文章也许能给你带来一些收获,但或许会令你更加的迷茫,为什么会这样?因为:1.UCenter虽然足够强大,但正为它的强大,它的不少暗箱操作使得我们望而生畏,我们不害怕出 ...
- UCenter在JAVA项目中实现的单点登录应用实例
Comsenz(康盛)的UCenter当前在国内的单点登录领域占据绝对份额,其完整的产品线令UCenter成为了账号集成方面事实上的标准. 基于UCenter,可以将Comsenz旗下的Discuz! ...
- 一步一步学Silverlight 2系列(15):数据与通信之ASMX
概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...
- 一步一步学Silverlight 2系列(14):数据与通信之WCF
一步一步学Silverlight 2系列(14):数据与通信之WCF 概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框 ...
- 谈谈Nginx和php之间是交互与通信的方式
Nginx是俄国人最早开发的Webserver,现在已经风靡全球,相信大家并不陌生.PHP也通过二十多年的发展来到了7系列版本,更加关注性能.这对搭档在最近这些年,叱咤风云,基本上LNMP成了当下的标 ...
随机推荐
- AngularJs-数据绑定
前言: 我们在做前端工作最重要的是把数据能展示给用户看,展示的时候就是把数据绑定给某个元素. 1,简单的数据绑定 html: <!DOCTYPE html> <html ng-app ...
- 每天一个linux命令(8):cat 命令
cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. 1.命令格式: cat [选项] [文件] ...
- Mobile Web
Silun来给大家介绍几个常见的移动浏览器标签~ 当当当~ <meta name="apple-mobile-web-app-capable" content="y ...
- IntelliJ13+tomcat+jrebel实现热部署(亲测可用)
网上有很多介绍intellij idea整合jrebel插件实现热部署的文章,但是有的比较复杂,有的不能成功,最后经过各种尝试,实现了整合,亲测可用!步骤说明如下: 一.先下载jrebel安 ...
- 【POJ 2923】Relocation(状压DP+DP)
题意是给你n个物品,每次两辆车运,容量分别是c1,c2,求最少运送次数.好像不是很好想,我看了网上的题解才做出来.先用状压DP计算i状态下,第一辆可以运送的重量,用该状态的重量总和-第一辆可以运送的, ...
- JS 在线网站
JS 在线压缩网站 国内压缩js网站http://tool.css-js.com/ uglifyjs 压缩js网站http://lisperator.net/uglifyjs JS在线格式化网站 ht ...
- iOS代码工具箱再续
if (CGRectContainsPoint(self.menuView.frame, point)) { point = [self.view convertPoint:point toView ...
- 依赖管理工具漫谈--从Maven,Gradle到Go
http://jolestar.com/dependency-management-tools-maven-gradle/
- Jquery的初识
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- MongoDB之bson的介绍
MongoDB之bson的介绍 1. 什么是bson BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JS ...