开发

接入说明

查找基本信息

  • Step1:通过公司公共账号登陆开源联盟平台并提交申请
    登录小程序开源联盟平台
    https://smartprogram.baidu.com/developer/opensource.html)
    请使用百度账号登录开源联盟平台。如果您还没有百度账号,请先注册百度账号
    https://passport.baidu.com/v2) 注册完成后即可登陆。 点击加入后提交申请表可。
  • Step2:平台提供成员联盟关键信息
    开源联盟平台提供联盟方关键认证信息,如下表所示:
字段 说明 备注
union_id 密钥Key 一个联盟成员即一个应用方
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(即第二步的字符串)+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
public function getSign ($params, $secret)
{
// 先删除参数中不要的参数
unset($params['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
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;
}