ldms
以下关于文件的阐述以及代码的样例,均以 PHP 程序为例。

UCenter 的 API 接口文件必须存放于应用程序根目录的“api/”目录中,且文件名可以自定义,默认为 uc.php,即“api/uc.php”。文件结构可分为 4 部分,包含 12 个接口项目。第 1 部分为常量定义、第 2 部分为通知方式判断以及初始化输入参数、第 3 部分为接口类代码段、第 4 部分为函数定义。

1、常量定义

define(\'UC_CLIENT_VERSION\', \'1.5.0\'); //note UCenter 版本标识
define(\'UC_CLIENT_RELEASE\', \'20081031\');
define(\'API_DELETEUSER\', 1); //note 用户删除 API 接口开关
define(\'API_RENAMEUSER\', 1); //note 用户改名 API 接口开关
define(\'API_GETTAG\', 1); //note 获取标签 API 接口开关
define(\'API_SYNLOGIN\', 1); //note 同步登录 API 接口开关
define(\'API_SYNLOGOUT\', 1); //note 同步登出 API 接口开关
define(\'API_UPDATEPW\', 1); //note 更改用户密码 开关
define(\'API_UPDATEBADWORDS\', 1); //note 更新关键字列表 开关
define(\'API_UPDATEHOSTS\', 1); //note 更新域名解析缓存 开关
define(\'API_UPDATEAPPS\', 1); //note 更新应用列表 开关
define(\'API_UPDATECLIENT\', 1); //note 更新客户端缓存 开关
define(\'API_UPDATECREDIT\', 1); //note 更新用户积分 开关
define(\'API_GETCREDITSETTINGS\', 1); //note 向 UCenter 提供积分设置 开关
define(\'API_GETCREDIT\', 1); //note 获取用户的某项积分 开关
define(\'API_UPDATECREDITSETTINGS\', 1); //note 更新应用积分设置 开关
define(\'API_RETURN_SUCCEED\', \'1\');
define(\'API_RETURN_FAILED\', \'-1\');
define(\'API_RETURN_FORBIDDEN\', \'-2\');
 
常量定义部分定义了接口所用到的 14 个接口项目的开关设置,“1”为开启“0”为关闭。如果开启,则代码段运行后返回 API_RETURN_SUCCEED,否则返回 API_RETURN_FORBIDDEN。接口运行失败则返回 API_RETURN_FAILED。
 

2、通知方式判断以及初始化输入参数

if(!defined(\'IN_UC\')) {
error_reporting(0);
set_magic_quotes_runtime(0);
define(\'DISCUZ_ROOT\', substr(dirname(__FILE__), 0, -3));
defined(\'MAGIC_QUOTES_GPC\') || define(\'MAGIC_QUOTES_GPC\', get_magic_quotes_gpc());
require_once DISCUZ_ROOT.\'./config.inc.php\';
$_DCACHE = $get = $post = array();
$code = @$_GET[\'code\'];
parse_str(_authcode($code, \'DECODE\', UC_KEY), $get);
if(MAGIC_QUOTES_GPC) {
$get = _stripslashes($get);
}
$timestamp = time();
if($timestamp - $get[\'time\'] > 3600) {
exit(\'Authracation has expiried\');
} if(empty($get)) {
exit(\'Invalid Request\');
}
$action = $get[\'action\'];
require_once DISCUZ_ROOT.\'./uc_client/lib/xml.class.php\';
$post = xml_unserialize(file_get_contents(\'php://input\'));
if(in_array($get[\'action\'], array(\'test\', \'deleteuser\', \'renameuser\', \'gettag\', \'synlogin\', \'synlogout\', \'updatepw\', \'updatebadwords\', \'updatehosts\', \'updateapps\', \'updateclient\', \'updatecredit\', \'getcreditsettings\', \'updatecreditsettings\'))) {
require_once DISCUZ_ROOT.\'./include/db_\'.$database.\'.class.php\';
$GLOBALS[\'db\'] = new dbstuff;
$GLOBALS[\'db\']->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, true, $dbcharset);
$GLOBALS[\'tablepre\'] = $tablepre;
unset($dbhost, $dbuser, $dbpw, $dbname, $pconnect);
$uc_note = new uc_note();
exit($uc_note->$get[\'action\']($get, $post));
} else {
exit(API_RETURN_FAILED);
}
} else {
define(\'DISCUZ_ROOT\', $app[\'extra\'][\'apppath\']);
require_once DISCUZ_ROOT.\'./config.inc.php\';
require_once DISCUZ_ROOT.\'./include/db_\'.$database.\'.class.php\';
$GLOBALS[\'db\'] = new dbstuff;
$GLOBALS[\'db\']->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, true, $dbcharset);
$GLOBALS[\'tablepre\'] = $tablepre;
unset($dbhost, $dbuser, $dbpw, $dbname, $pconnect);
}
通过常量 IN_UC 来判断接口文件是通过远程 HTTP 方式访问还是直接包含方式调用

2、接口代码段

接口类名称为 uc_note ,接口名称作为此类的一个方法,uc_note 代码结构大体如下:
class uc_note {
var $dbconfig = \'\';
//var $db = \'\';
var $appdir = \'\';
function _serialize($arr, $htmlon = 0) {
if(!function_exists(\'xml_serialize\')) {
include_once DISCUZ_ROOT.\'./uc_client/lib/xml.class.php\';
}
return xml_serialize($arr, $htmlon);
}
function uc_note() {
$this->appdir = substr(dirname(__FILE__), 0, -3);
$this->dbconfig = $this->appdir.\'./config.inc.php\';
}
function test($get, $post) {
return API_RETURN_SUCCEED;
}
function deleteuser($get, $post) {
/*代码省略*/
return API_RETURN_SUCCEED;
}
/* 更多接口项目 */
}
 
具体可以参考Discuz7.0.0代码中的/api/uc.php

test

此接口供仅测试连接。当 UCenter 发起 test 的接口请求时,如果成功获取到接口返回的 API_RETURN_SUCCEED 值,表示 UCenter 和应用通讯正常。

deleteuser

当 UCenter 删除一个用户时,会发起 deleteuser 的接口请求,通知所有应用程序删除相应的用户。
输入的参数放在 $get[\'ids\'] 中,值为用逗号分隔的用户 ID。如果删除成功则输出 API_RETURN_SUCCEED。
deleteuser 接口示例 (PHP)

renameuser

当 UCenter 更改一个用户的用户名时,会发起 renameuser 的接口请求,通知所有应用程序改名。
输入的参数 $get[\'uid\'] 表示用户 ID,$get[\'oldusername\'] 表示旧用户名,$get[\'newusername\'] 表示新用户名。如果修改成功则输出 API_RETURN_SUCCEED。
renameuser 接口示例 (PHP)

updatepw

当用户更改用户密码时,此接口负责接受 UCenter 发来的新密码。
输入的参数 $get[\'username\'] 表示用户名,$get[\'password\'] 表示新密码。如果修改成功则输出 API_RETURN_SUCCEED。
updatepw 接口示例 (PHP)

gettag

如果应用程序存在标签功能,可以通过此接口把应用程序的标签数据传递给 UCenter。
输入的参数放在 $get[\'id\'] 中,值为标签名称。输出的数组需经过 uc_serialize 处理。
integer [0] 标签名称
array [1] 标签数据
mixed [\'xxx\'] 自定义
自定义多个数组项,索引名任意,一同返回给 UCenter。为了保证应用间数据的共享,您需要在“应用管理管理”的“标签单条显示模板”和“标签模板标记说明”设置模板和说明。模板中 “{xxx}”表示标签数据的索引,代表相应的数据。如扩展数据模板中的“{image}”将显示“[\'image\']”数组项的内容。
gettag 接口示例 (PHP)

synlogin

如果应用程序需要和其他应用程序进行同步登录,此部分代码负责标记指定用户的登录状态。
输入的参数放在 $get[\'uid\'] 中,值为用户 ID。此接口为通知接口,无输出内容。同步登录需使用 P3P 标准
synlogin 接口示例 (PHP)

synlogout

如果应用程序需要和其他应用程序进行同步退出登录,此部分代码负责撤销用户的登录的状态。
此接口为通知接口,无输入参数和输出内容。同步退出需使用 P3P 标准
synlogout 接口示例 (PHP)

updatebadwords

当 UCenter 的词语过滤设置变更时,此接口负责通知所有应用程序更新后的词语过滤设置内容。
设置内容用 POST 方式提交到接口。接口运行完毕输出 API_RETURN_SUCCEED。
updatebadwords 接口示例 (PHP)

updatehosts

当 UCenter 的域名解析设置变更时,此接口负责通知所有应用程序更新后的域名解析设置内容。
设置内容用 POST 方式提交到接口。接口运行完毕输出 API_RETURN_SUCCEED。
updatehosts 接口示例 (PHP)

updateapps

当 UCenter 的应用程序列表变更时,此接口负责通知所有应用程序更新后的应用程序列表。
设置内容用 POST 方式提交到接口。接口运行完毕输出 API_RETURN_SUCCEED。
updateapps 接口示例 (PHP)

updateclient

当 UCenter 的基本设置信息变更时,此接口负责通知所有应用程序更新后的基本设置内容。
设置内容用 POST 方式提交到接口。接口运行完毕输出 API_RETURN_SUCCEED。
updateclient 接口示例 (PHP)

updatecredit

当某应用执行了积分兑换请求的接口函数 uc_credit_exchange_request() 后,此接口负责通知被兑换的目的应用程序所需修改的用户积分值。
输入的参数 $get[\'credit\'] 表示积分编号,$get[\'amount\'] 表示积分的增减值,$get[\'uid\'] 表示用户 ID。
updatecredit 接口示例 (PHP)

getcreditsettings

此接口负责把应用程序的积分设置传递给 UCenter,以供 UCenter 在积分兑换设置中使用。
此接口无输入参数。输出的数组需经过 uc_serialize 处理。
输出的数组单条结构:
1 维 KEY 2 维 KEY
array [n] 积分编号 string [0] 积分名称
string [1] 积分单位
如:
array(
        \'1\' => array(\'威望\', \'\'),
        \'2\' => array(\'金钱\', \'枚\'),
)
 
getcreditsettings 接口示例 (PHP)

updatecreditsettings

此接口负责接收 UCenter 积分兑换设置的参数。
输入的参数放在 $get[\'credit\'] 中,值为设置的参数数组。接口运行完毕输出 API_RETURN_SUCCEED。
输入的数组单条结构:
1 维 KEY 2 维 KEY
array [appid] 应用程序 ID integer [\'appiddesc\'] 积分兑换的目标应用程序 ID
integer [\'creditdesc\'] 积分兑换的目标积分编号
integer [\'creditsrc\'] 积分兑换的源积分编号
string [\'title\'] 积分名称
string [\'unit\'] 积分单位
integer [\'ratio\'] 积分兑换比率
如:
array(
        \'1\' => array(
                \'appiddesc\' => 2,
                \'creditdesc\' => 1,
                \'creditsrc\' => 1,
                \'title\' => \'金钱\',
                \'unit\' => \'枚\',
                \'ratio\' => 2,
        ),
)
 
updatecreditsettings 接口示例 (PHP)

getcredit

此接口用于把应用程序中指定用户的积分传递给 UCenter。
输入的参数 $get[\'uid\'] 为用户 ID,$get[\'credit\'] 为积分编号。接口运行完毕输出积分值。
getcredit 接口示例 (PHP)

4、函数定义

接口函数中必须包含以下函数,否则无法正确对 UCenter 传递过来的数据进行解码。
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));
}
}
function uc_serialize($arr, $htmlon = 0) {
include_once UC_CLIENT_ROOT.\'./lib/xml.class.php\';
return xml_serialize($arr, $htmlon);
}
function uc_unserialize($s) {
include_once UC_CLIENT_ROOT.\'./lib/xml.class.php\';
return xml_unserialize($s);
}
 

分类:

技术点:

相关文章: