UCenter (四) 应用
UCenter 安装好了,也明白了各个目录及文件的用法了。现在说说UCenter是怎么做为Discuz!的用户中心。
Discuz!下面有个uc_client,这个是Discuz!与UCenter信息交换的地方。里面的client.php是核心。
如果设置了UC_CONNECT = ‘mysql’,(一般Discuz!和UCenter的数据库主机是一样的时候会这么设置)那么Discuz!会通过uc_client目录,直接读取数据库。仔细一个,发现uc_client就是把整个UCenter的前台部分提取了出来。这个情况下UCenter的安装对Discuz!来说只是建了一个可供其操作的数据库[1]。
注[1]:其实这是一种有点不负责任的说法。人物的头像可是存在UCenter的data/avatar目录下的,对头像的操作是不能仅仅通过操作数据库而做到的,不过也是仅此而已。同步登录与登出的问题也许会有更好的解决方法。
如果没有设置UC_CONNECT = ‘mysql’ ,那么通信时就是通过HTTP请求而从UCenter中获取数据的。其实UCenter的前台就是接口。
其实Discuz!直接操作UCenter的数据库与调用UCenter接口而由UCenter来操作自己的数据库,结果上是完全一样的,只是在同一个服务器下直接操作数据库的话,效率上会高一点,因为少了个HTTP请求的损耗。
以用户在Discuz!注册帐号为例(这里不谈Discuz对自己数据库的操作),用户名为myusername,密码为mypassword:
直接读取数据库:
调用的是uc_api_mysql(‘user’,’register’,array(‘username’=>’myusername’,’password’=>’mypassword’));
在这个调用里主要的操作是:
$uc_controls[‘user’] = new usercontrol();
return $uc_controls[‘user’]->onregister($args);
//这里的$args = array(‘username’=>’myusername’,’password’=>’mypassword’)
uc_client目录下的control里面有个user.php里面定义了usercontrol类。
调用UCenter接口的方式调用的是uc_api_post,参数与uc_api_mysql是一样的:
return uc_fopen2($ucapi);
//uc_fopen2 是对$ucapi的http请求。
/*$ucapi = UC_API.’index.php?m=user&a=register&input=$input’,这个$input是对那个数组参数的加密*/
//UC_API 在Discuz!的config.inc.php里定义了。
而 UC_API.’index.php?m=user&a=register&input=$input’这个做的事就是操作自己的数据库,过程和上面那个过程是一样的。
经过对比可以明显发现,uc_api_post是一个http请求之后获得数据,uc_api_mysql是直接从数据库里获得数据。所以,UCenter的应用通常与UCenter在同一个服务器的话会有点效率的优势,这个效率就体现在http响应上。
如果非Discuz!等Comsenz的东西,比如是自己写的一个应用,想要整合UCenter的话,且与UCenter在同一个服务器的话,也可以自己写个uc_client直接操作UCenter的数据库。如果没在同一个服务器的话,直接调用UCenter接口就好了。
对于接口调用的安全性问题,UCenter做得还是比较到位的。上面的例子之所以没有直接写与$input的内容,是因为$input是把”agent=$agent&time=$time&username=myusername&password=mypassword”经过了一个UC_KEY加密之后的密文,$agent是http请求的User-Agent,$time是当前时间戳。UCenter获取到这个密文之后,也是经过同一个UC_KEY来解密成明文的。没有这个UC_KEY,任何人截取到这个URL也不知道其中的内容。
这个加密和解密用同一个UC_KEY的异或运算是非常之经典的。可以找到authcode这个函数,稍稍研究一下。