第三方SDK开发指南
目前百度"云推送"提供的SDK只有PHP及Java两种语言, 我们后续会根据开发者的实际使用情况推出更多语言版本的SDK工具包. 同时我们也欢迎第三方开发者自由开发并发布各种语言的SDK工具包. 本文档描述了在使用RestAPI接入云推送服务的过程中需要注意的一些问题.
请求URL
按照百度Http Open API规范,Baidu Channel提供如下REST风格的http和https接口:
[GET|POST] http[s]://api.tuisong.baidu.com/rest/3.0/{class}/{method}?{query_string}
{class}: 为restapi待访问资源的类别,目前有push,tag,app,report,timer, topic等。
{method}: 操作方法名称。
{query_string}:
{query_string}由通用参数部分和具体API调用参数部分组成。
{query_string}中的key/value对都必须经过urlencode处理,且必须是UTF-8编码。
对于GET请求,{query_string}必须放在QUERY参数中传递,即放在“?”后面。
对于POST请求,{query_string}放在POST参数中传递。
目前查询接口同时支持POST和GET方式,非查询接口仅支持POST方式。
公共请求参数
下表内容为每次请求需要携带的公共参数列表。
参数名
类型
必需
描述
apikey
string
是
应用的api key,用于标识应用,
timestamp
number
是
用户发起请求时的unix时间戳。本次请求签名的有效时间为该时间戳向后10分钟
sign
string
是
调用参数签名值,与apikey成对出现。用于防止请求内容被篡改, 生成方法请参考:签名算法
expires
number
否
用户指定本次请求签名的失效时间。格式为unix时间戳形式,用于防止 replay 型攻击。为保证防止 replay攻击算法的正确有效,请保证客户端系统时间正确
device_type
number
否
当一个应用同时支持多个设备平台类型(比如:Android和iOS),请务必设置该参数。其余情况可不设置。具体请参见:device_type参数使用说明
关于device_type参数使用说明
3.0版本的云推送服务,为了更好的统计数据及简化使用,对应用的支持平台进行区分,每个应用仅支持一个平台,2.0版本中的每个应用在升级至3.0后,将拆分为两个相同appid的应用,所以需要在使用SDK的过程中设置 device_type 参数指定操作哪一个平台的应用,device_type 的取值有以下两种:
3:android
4:iOS
HTTP请求Header
Content-Type
http数据交互请求参数请确保为UTF-8编码, 服务端在接收请求时,将直接放弃处理其它编码格式,所以在发送请求前,必须正确设置Content-Type为:
Content-Type: application/x-www-form-urlencoded;charset=utf-8
User-Agent
服务器端通过UA来识别来自SDK的请求并获取SDK执行环境的相关信息(操作系统版本, 语言版本, SDK名称及版本等),SDK在发送请求时,必须携带具有一定格式的User-Agent,否则服务端将直接拒绝响应请求。
UA格式与正常浏览器UA类似, 使用 '/' 分隔名称与版本 附加信息使用括号(),多个项目间使用空格进行分隔。
格式:
BCCS_SDK/3.0 (操作系统版本信息) 开发语言/开发语言版本 (SDK名称及版本信息) 其它扩展模块/版本(附加信息)
注意: 目前restapi版本号只支持 '3.0', 其它版本将被直接拒绝
示例:
User-Agent: BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0
响应格式
服务端的响应格式均为json内容. 以下若无特别说明,仅描述正确响应中 response_params 中内容。
正确响应
{
"request_id":12394838223,
"response_params":
{
"channel_id":"124343-32323-12323",
"channel_token":"asdfwerf24f2fsdafa-23423asfdsadf"
}
}
错误响应
{
"request_id":12394838223,
"error_code":30602,
"error_msg":"Request params not valid"
}
错误码定义
签名算法
云推送服务API使用的签名算法如下:
获取请求的http method;
获取请求的url,包括host和sheme,但不包括query_string的部分;
将所有参数(包括GET或POST的参数,但不包含签名字段)格式化为“key=value”格式,如“k1=v1”、“k2=v2”、“k3=v3”;
将格式化好的参数键值对以字典序升序排列后,拼接在一起,如“k1:v1,k2 :v2,k3:v3”,并将http method和url按顺序拼接在这个字符串前面;
在拼接好的字符串末尾追加上应用的secret_key,并进行urlencode,形成base_string;
上述字符串的MD5值即为签名的值:
即可简单描述为: sign = MD5( urlencode( $http_method$url$k1=$v1$k2=$v2$k3=$v3$secret_key ));
例如,在需要发送一个POST请求给 /test/echo, 并且参数为:
secret_key:87772555E1C16715EBA5C85341684C58
apikey:Ljc710pzAa99GULCo8y48NvB
expires:1313293565
timestamp:1427180905
则参于签名的字符串:
POSThttp://api.tuisong.baidu.com/rest/3.0/test/echoapikey=Ljc710pzAa99GULCo8y48NvBexpires=1313293565timestamp=142718090587772555E1C16715EBA5C85341684C58
对以上字符串进行urlencode后再计算md5结果,即为本次请求的签名值.
注意: 关于urlencode,由于不同语言使用的规范略有不同。在实现时请以php urlencode方法为准。
PHP签名算法示例
/**
* $secret_key //应用的secret key
* $method //GET或POST
* $url url
* $arrContent //请求参数(包括GET和POST的所有参数,不含计算的sign)
* return $sign string
**/
function genSign($secret_key, $method, $url, $arrContent) {
$gather = $method.$url;
ksort($arrContent);
foreach($arrContent as $key => $value) {
$gather .= $key.'='.$value;
}
$gather .= $secret_key;
$sign = md5(urlencode($gather));
return $sign;
}
$secret_key = 'xxxxxxxx';//此处替换为应用的secret key
$method = 'POST';
$url = 'http://{domain}/rest/3.0/{class}/{method}';
$arrContent = array(
'apikey'=>'fdafadAfdsafadsDrfeareV',
'timestamp'=>1313293563,
'expires'=>1313293565,
);
$sign = genSign($secret_key, $method, $url, $arrContent);
NodeJS签名算法示例
/**
* 生成请求签名及uri编码
*/
var crypto = require('crypto');
// 兼容php的urlencode
function fullEncodeURIComponent (str) {
var rv = encodeURIComponent(str).replace(/[!'()*~]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase();
});
return rv.replace(/\%20/g,'+');
}
/**
* 生成请求签名
*
* @param {object} reqParams, 由url.parse解析出来的对象内容,描述请求的位置和url及参数等信息的对象
* @param {object} postParams post表单内容
* @param {string} secretKey 开发者中心的SK
* @return {string} 签名值
*/
var singKey = function (reqParam, postParmas, secretKey) {
var basekey = "";
var method = reqParam.method.toUpperCase();
var baseurl = reqParam.href;
var query = reqParam.query || false;
var param = {};
var paramStr = '';
if (query) {
query = querystring.parse(query);
for ( var key in query) {
param[key] = query[key];
}
}
if (postParmas) {
for ( var key in postParmas) {
param[key] = postParmas[key];
}
}
var keys = Object.keys(param).sort();
keys.forEach(function (key) {
paramStr += key + "=" + param[key];
})
basekey = method + baseurl + paramStr + secretKey;
console.log("basekey : ", basekey);
var md5 = crypto.createHash('md5');
basekey = fullEncodeURIComponent(basekey);
md5.update(basekey);
return md5.digest('hex');
}
module.exports = {
singKey:singKey
};
其它语言第三方SDK列表
欲将您的SDK添加在这里, 请发送邮件至:< push-support@baidu.com >