# 设备token
# 获取token
HTTP Method:POST
请求地址:http://dc.hivoice.cn/rest/v2/device/activate
参数 | 类型 | 必填 | 描述 |
---|---|---|---|
appKey | String | Y | 应用KEY |
deviceSn | String | N | 客户认可的设备唯一标识(由客户端APP设置) |
udid | String | Y | 设备唯一标识(认证授权生成) |
timestamp | long | Y | 访问时间戳,Unix时间戳 |
appVersion | String | N | 应用版本号 |
pkgName | String | N | 包名 |
imei | String | N | 设备的IMEI |
macAddress | String | N | 设备MAC地址 |
wifiSsid | String | N | WIFI的名称 |
telecomOperator | String | N | 运营商 |
bssId | String | N | 当前的接入点MAC地址 |
productName | String | N | 设备名称 |
productModel | String | N | 设备型号名称 |
productMfr | String | N | 制造商名称 |
productOs | String | N | 操作系统 |
productOsVersion | String | N | 操作系统版本号 |
hardwareSn | String | N | 厂商硬件序列号 |
memo | String | N | 备注 |
signature | String | Y | 数据签名 |
返回值
参数 | 类型 | 必填 | 描述 |
---|---|---|---|
returnCode | String | Y | 响应code,成功为0,具体见错误码定义 |
message | String | Y | 响应描述 |
costTime | Integer | Y | 响应时间,单位:毫秒 |
result | Object | Y | 返回的结果数据 |
└token | String | Y | 令牌 |
└validTime | String | Y | 令牌有效时间 |
返回结果示例:
{
"returnCode": "dc_0000",
"message": "成功",
"costTime": 259,
"result": {
"token": "442a7897-9c1b-4230-ac0e-c1365c5bf1b9",
"validTime": 1928517
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 刷新token
HTTP Method:POST
请求地址:http://dc.hivoice.cn/rest/v2/token/refresh
参数 | 类型 | 必填 | 描述 |
---|---|---|---|
appKey | String | Y | 应用KEY |
udid | String | Y | 设备唯一标识(认证授权生成) |
timestamp | long | Y | 访问时间戳,Unix时间戳 |
token | String | Y | 当前有效的token |
signature | String | Y | 数据签名 |
返回值
参数 | 类型 | 必填 | 描述 |
---|---|---|---|
returnCode | String | Y | 响应code,成功为0,具体见错误码定义 |
message | String | Y | 响应描述 |
costTime | Integer | Y | 响应时间,单位:毫秒 |
result | Object | Y | 返回的结果数据 |
└token | String | Y | 令牌 |
└validTime | String | Y | 令牌有效时间 |
返回结果示例:
{
"returnCode": "dc_0000",
"message": "成功",
"costTime": 259,
"result": {
"token": "442a7897-9c1b-4230-ac0e-c1365c5bf1b9",
"validTime": 1928517
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 签名规则
内容签名生成规则:
1)将所有请求参数的值放入List中,注意:计算sign时所有参数不应进行URLEncode;
2)将格式化后的参数以字典序升序排列,拼接在一起,注意字典序中大写字母在前,空值(null)使用空字符串代替;
3)将B形成字符串获取SHA1摘要,形成一个40位的十六进制(字母大写)字符串,即为本次请求signature(签名)的值;
然后再POST请求时,所有参数的值都应进行URLEncode;(参数值是数字或字母的可以不进行URLEncode)
该签名值基本可以保证请求是合法者发送且参数没有被修改,但无法保证不被偷窥。 签名构造示例代码
public String buildActivateSignature(ActivateReqVO reqVO, String appSecret) {
List<String> params = new ArrayList<String>();
params.add(reqVO.getUdid());
params.add(reqVO.getDeviceSn());
params.add(reqVO.getAppKey());
params.add(String.valueOf(reqVO.getTimestamp()));
params.add(reqVO.getPkgName());
params.add(reqVO.getAppVersion());
params.add(reqVO.getImei());
params.add(reqVO.getMacAddress());
params.add(reqVO.getWifiSsid());
params.add(reqVO.getTelecomOperator());
params.add(reqVO.getBssId());
params.add(reqVO.getProductName());
params.add(reqVO.getProductModel());
params.add(reqVO.getProductMfr());
params.add(reqVO.getProductOs());
params.add(reqVO.getProductOsVersion());
params.add(reqVO.getHardwareSn());
params.add(reqVO.getMemo());
params.add(appSecret);
String signature = buildSignature(params);
logger.debug("generated signature: " + signature);
return signature;
}
/**
* 对参数列表构造响应签名
*
* @param params
* @return
*/
public static String buildSignature(List<String> params) {
if (params == null || params.isEmpty()) {
return "";
}
// 升序排序参数值
Collections.sort(params);
StringBuilder sb = new StringBuilder();
for (String param : params) {
sb.append(param == null ? "" : param);
}
return getSHA1Digest(sb.toString());
}
/**
* 将字符串进行SHA1获取摘要,摘要为十六进制字符串
*
* @param data
* @return
* @throws Exception
*/
public static String getSHA1Digest(String data) {
String digest = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] bytes = md.digest(data.getBytes("UTF-8"));
digest = byte2hex(bytes);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return digest;
}
/**
* 二进制转十六进制字符串
*
* @param bytes
* @return
*/
private static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 错误码定义及描述
errorCode | errorMsg | 描述 |
---|---|---|
dc_0000 | 成功 | 成功 |
dc_0001 | 应用不存在 | 检查使用appKey是否已经创建 |
dc_0002 | 请求时间戳超出了请求有效期 | 设备端时间和当前时间的差值绝对值不能超过10分钟 |
dc_0003 | 签名错误 | 检查appKey和appSecret是否匹配 |
dc_0004 | 没有激活权限 | 检查认证授权流程是否成功 |
dc_0005 | 超过了最大激活频率 | 联系管理员 |
dc_0006 | 无效的设备token | 重新调用设备激活接口获取最新的设备TOKEN |
dc_0007 | 必填参数的参数值不能为空 | 参考API中参数的非空说明 |
dc_9999 | 其他错误 | 联系管理员 |