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成了当下的标 ...
随机推荐
- Weblogic 启动报错:java.lang.NoClassDefFoundError
Weblogic 启动报错:java.lang.NoClassDefFoundError ####<2015-6-17 下午03时30分47秒 CST> <Error> &l ...
- Java设计模式-访问者模式(Visitor)
访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化.访问者模式适用于数据结构相对稳定算法又易变化的系统.因为访问者模式使得算法操作增加变得容易.若系统数据结构对象易于变化,经 ...
- Java基础-多线程
介绍 操作系统能同时运行几个程序,每个独立运行的程序又称之为进程. 对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程.线程提供了多任务处理的能力 用进程和线程的观点来研究软件是当今普遍采 ...
- 【BZOJ-2295】我爱你啊 暴力
2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 202 Solved: 141[Submit][St ...
- BZOJ-1226 学校食堂Dining 状态压缩DP
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...
- 高斯混合聚类及EM实现
一.引言 我们谈到了用 k-means 进行聚类的方法,这次我们来说一下另一个很流行的算法:Gaussian Mixture Model (GMM).事实上,GMM 和 k-means 很像,不过 G ...
- Mysql 学习-索引的设计原则
索引的设计不合理或者缺少索引都会对数据库和应用程序的性能造成障碍.高效的索引对获的良好性能非常重要.设计索引是,应该考虑一下准则: (1)索引并非语讹夺越好,若一个表中有大量索引,不仅占用磁盘空间,而 ...
- Android学习笔记02-Mac下编译java代码
在Mac OS上配置JDK 1.7. 一 下载 Mac版本的JDK1.7 从以下下载地址,下载Mac版本的JDk1.7 安装文件 jdk-7u79-macosx-x64.dmg. http://www ...
- hdu 2050 折线分割平面
训练递推用题,第一次做这个题,蒙的,而且对了. #include <stdio.h> int main(void) { int c,a; scanf("%d",& ...
- FCKeditor漏洞利用
FCKeditor漏洞利用 查看编辑器版本 FCKeditor/_whatsnew.html fckeditor/editor/dialog/fck_about.html —————————————— ...