ucenter 简单分析与同步机制

来源:互联网 发布:淘宝比较潮的男装店 编辑:程序博客网 时间:2024/05/01 10:58

ucenter采用MVC架构,多数用于同步各个应用中的用户数据,实现用户的一站式注册、登录、退出以及社区其他数据的交互。

简单分析

index.php入口文件

$m = getgpc('m'); //判断加载哪一个Model$a = getgpc('a'); //判断加载哪一个Controlif(empty($m) && empty($a)) {    header('Location: admin.php');    exit;}...//加载基类,基类中定义了很多的方法,所有控制器类都继承于该基类if(file_exists(UC_ROOT.RELEASE_ROOT.'model/base.php')) {    require UC_ROOT.RELEASE_ROOT.'model/base.php';} else {    require UC_ROOT.'model/base.php';}...//判断是否加载的是指定的modelif(in_array($m, array('app', 'frame', 'user', 'pm', 'pm_client', 'tag', 'feed', 'friend', 'domain', 'credit', 'mail', 'version'))) {    if(file_exists(UC_ROOT.RELEASE_ROOT."control/$m.php")) {        include UC_ROOT.RELEASE_ROOT."control/$m.php";    } else {        include UC_ROOT."control/$m.php";    }    $classname = $m.'control'; //构造control类,如$m=user时control就为usercontrol    $control = new $classname();    $method = 'on'.$a; //构造方法名    if(method_exists($control, $method) && $a{0} != '_') {        $data = $control->$method();        echo is_array($data) ? $control->serialize($data, 1) : $data;        exit;    } elseif(method_exists($control, '_call')) { //如果方法存在且不是私有方法则执行该方法        $data = $control->_call('on'.$a, '');        echo is_array($data) ? $control->serialize($data, 1) : $data;        exit;    } else {        exit('Action not found!');    }}

例子
xxx/index.php?m=user&a=login
这样,就会初始化usercontrol并调用onlogin方法。

model层直接与数据库交互,control层与model层交互,得到结果,返回给view。
如果我们要扩展自己的方法该怎么办?
首先,增加model类,定义我们所需要的方法,直接与DB进行交互。
其次,增加control类,并继承自base,定义on{xxxx}方法,与相对的model交互,并返回结果。


同步登录通信原理

原文参考地址:http://www.jb51.net/article/54297.htm

discuz登录为例的流程:

  • 用户登录discuz,通过logging.php文件中的函数uc_user_login对post过来的数据进行验证,也就是对username和password进行验证
  • 如果验证成功,将调用文件路径为uc_client/client.php中的函数uc_user_synlogin,在这个函数中调用 uc_api_post('user', 'synlogin', array('uid'=>$uid))
  • 然后这个函数后向Ucenter的index.php传递数据,index.php接受传递的数据,获得model为user,action为synlogin的值。
  • 然后Ucenter的index.php调用control/user.php类中的onsynlogin方法,通过foreach循环,以生成javascript(<script type="text/javascript" src="{应用url?time=时间戳&code=含有用户信息的加密字符串}"></script>)并加载的方式通知uc应用列表中开启同步登陆的应用进行同步登录;即通过get方式传递给各个应用目录中api下的uc.php一些数据。
  • uc.php接收通知并处理get过来的数据,用authcode对url中参数code进行解密得出用户信息,以存cookie等方式进行同步登录。

用户信息加密解密使用的函数

function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {    $ckey_length = 4;    $key = md5($key ? $key : UC_KEY);    $keya = md5(substr($key, 0, 16));    $keyb = md5(substr($key, 16, 16));    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';    $cryptkey = $keya.md5($keya.$keyc);    $key_length = strlen($cryptkey);    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;    $string_length = strlen($string);    $result = '';    $box = range(0, 255);    $rndkey = array();    for($i = 0; $i <= 255; $i++) {        $rndkey[$i] = ord($cryptkey[$i % $key_length]);    }    for($j = $i = 0; $i < 256; $i++) {        $j = ($j + $box[$i] + $rndkey[$i]) % 256;        $tmp = $box[$i];        $box[$i] = $box[$j];        $box[$j] = $tmp;    }    for($a = $j = $i = 0; $i < $string_length; $i++) {        $a = ($a + 1) % 256;        $j = ($j + $box[$a]) % 256;        $tmp = $box[$a];        $box[$a] = $box[$j];        $box[$j] = $tmp;        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));    }    if($operation == 'DECODE') {        if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {            return substr($result, 26);        } else {            return '';        }    } else {        return $keyc.str_replace('=', '', base64_encode($result));    }}

authcode()的四个参数,一般情况下只用到前三个:
$string 提供需要加密的字符串
$operation 加密方式,ENCODE是加密,DECODE是解密
$key 密钥,在整合程序时填写的密钥。






1 0
原创粉丝点击