开发

接入说明

查找基本信息

字段 说明 备注
union_id 联盟授权ID 一个联盟成员即一个应用方
union_key 别名:API KEY ,联盟方 API KEY
secret_key 密钥 Key
union_name 联盟方名称
  • Step3:ACCESS_TOKEN 获取
    采用 Client Credentials 方式,即应用公钥、密钥方式获取 Access Token ,后 Access Token 访问各服务接口。对于应用而言,其流程只有一步,即直接获取 Access Token 。
    使用 Client Credentials 获取 Access Token 需要应用在其服务端发送请求(推荐用POST方法)到百度 OAuth2.0 授权服务的 https://openapi.baidu.com/oauth/2.0/token 地址上,并带上以下参数:
字段 说明 备注
grant_type 必须参数 固定为 client_credentials
client_id 必须参数 Step2 中的 union_key
client_secret 必须参数 Step2 中的 secret_key
scope 必须参数 由百度联盟宿主平台提供值为:smartapp_opensource_openapi

返回格式如下:

1
2
3
4
5
6
7
8
{
"access_token":"1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328",
"expires_in":86400,
"refresh_token":"2.385d55f8615fdfd9edb7c4b5ebdc3e39.604800.1293440400-2346678-124328",
"scope":"smartapp_opensource_openapi",
"session_key":"ANXxSNjwQDugf8615OnqeikRMu2bKaXCdlLxn",
"session_secret":"248APxvxjCZ0VEC43EYrvxqaK4oZExMB"
}

备注:默认情况下,Access Token 的有效期为一个月,如果 Access Token 过期可以重新获取。

交互约定

认证后,开放给联盟成员平台使用的 API ,统一走百度开放平台(developer.baidu.com)进行 OpenAPI 授权后才能访问,访问入口统一走 https://openapi.baidu.com/rest/2.0/smartapp/ 进行请求,并带上统一的参数 access_token 和 union_sign 参数。union_sign 签名生成方法在下文。

返回数据统一放在 data 字段中,示例如下:

1
2
3
4
5
6
7
8
{
errno: 0,
msg: "success",
timestamp: 1548139897,
request_id: “468516b2fcae487881589ec5dd841062",
data: [
]
}

签名说明

1、 签名计算示例

① 所有请求参数按照字母先后顺序排列,注意参数中剔除 union_sign 和 access_token 字段
例如:
将 messageId、shopId、shopName、content、devicePosName、rewriteQuery、originalQuery、clientId、cuid、createTime、intents
排序为:
clientId、content、createTime、cuid、devicePosName、intents、messageId、originalQuery、rewriteQuery、shopId、shopName
② 把所有参数名和参数值进行拼装
例如:clientId=xxxx&content=xxxx&createTime=xxxx&cuid=xxxx&devicePosName=xxxx&intents=xxxx&messageId=xxxx&originalQuery=xxxx&rewriteQuery=xxxx&shopId=xxxxx&shopName=xxxx
③ 将密钥拼接到签名字符串最后面
例如:XXXX(即第二步的字符串)+ “&hsk=” + secret
④ 使用MD5进行加密

2、 签名函数和密钥说明

备注:签名计算的字串 secret ,即小程序联盟平台提供的 hsk ,可以登录开源联盟平台在“管理中心 -> 设置 -> 开发设置”中获取。

PHP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public function getSign ($params, $secret)
{
// 先删除参数中不要的参数
unset($params['union_sign']);
unset($params['access_token']);
// 先将参数以其参数名的字母升序进行排序
ksort($params);
// 遍历排序后的参数数组中的每一个key/value对
$str = '';
foreach ($params as $k => $v)
{
// 为key/value对生成一个key=value格式的字符串,并拼接到签名字符串后面
if(is_array($v))
{
$str .= "$k=".json_encode($v) . "&";
}
else
{
$str .= "$k=$v&";
}
}
// 将签名密钥拼接到签名字符串最后面
$str .= "hsk=" . $secret;
// 返回计算小写md5
return md5($str);
}

JAVA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
private static final String EXT_PARAM_SIGN = "union_sign";
private static final String EXT_PARAM_ACCESS_TOKEN = "access_token";

public static String sign(Map<String, String> params, String secret) {

// 签名字符串
StringBuffer s = new StringBuffer();

// 先将参数以其参数名的字母升序进行排序
List<String> paramList = Arrays.asList(params.keySet().toArray(new String[params.keySet().size()]));
Collections.sort(paramList);

// 遍历排序后的参数数组中的每一个key/value对
paramList.forEach(key -> {
// 为key/value对生成一个key=value格式的字符串,并拼接到签名字符串后面
String value = params.get(key);
if (!EXT_PARAM_SIGN.equals(key) && !EXT_PARAM_ACCESS_TOKEN.equals(key)) {
s.append(key).append("=").append(value).append("&");
}
});

// 将签名密钥拼接到签名字符串最后面
s.append("hsk=").append(secret);

// 返回待签名字符串的md5签名值
return Md5Util.encoderByMd5(s.toString());
}

/**
* 利用MD5进行加密
*
* @param str 待加密的字符串
*
* @return 加密后的字符串, 加密失败返回null
*/
public static String encoderByMd5(String str) {
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
byte[] result = md5.digest(str.getBytes());
StringBuffer sb = new StringBuffer();
for (byte aByte : result) {
String s = Integer.toHexString(0xff & aByte);
if (s.length() == 1) {
sb.append("0" + s);
} else {
sb.append(s);
}
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
System.out.println(e.getMessage());
}

return null;
}