# 授权认证

# 授权流程

授权包括获取事务ID、授权认证和授权确认,请按照顺序走授权流程,授权确认完成后代表授权成功,设备才有权限对接协议。

# STEP1:获取事务ID

HTTP Method:GET和POST
请求地址:http://product-auth.hivoice.cn/product-test/rest/v1/app_auth/trans

参数 类型 必填 描述
clientName String N 产品渠道
appKey String Y appKey
prodBatchCode String N 生产批次
sign String Y 签名串

返回值

参数 类型 必填
描述
errorCode String Y 响应code,成功为0,具体见错误码定义
errorMsg String Y 响应描述
costTime Integer Y 响应时间,单位:毫秒
result Object Y 返回的结果数据
└transId String Y 当前授权事务ID

返回结果示例

{
    "costTime": 2,
    "errorCode": "0",
    "errorMsg": "success",
    "result": {
        "transId": "599329c6f33f4710b1d830e9effd7ae1"
    }
}
1
2
3
4
5
6
7
8

# STEP2:授权认证

HTTP Method:GET和POST
请求地址:http://product-auth.hivoice.cn/product-test/rest/v1/app_auth/auth

参数 类型 必填
描述
transId String Y 当前事务时间戳(授权事务ID)
authFlag Integer Y 云端授权标记(1:授权成功 0:未成功),转授权时,该值为1
clientName String N 产品渠道
prodBatchCode String N 生产批次
appKey String Y appKey
productModel String Y 产品型号
wifi String N wifi信息
deviceId String Y 芯片唯一号
sign String Y 签名串

返回值

参数 类型 必填 描述
errorCode String Y 响应code,成功为0,具体见错误码定义
errorMsg String Y 响应描述
costTime Integer Y 响应时间,单位:毫秒
result Object Y 返回的结果数据
└transId String Y 当前授权事务ID
└udid String Y 授权码(为空表示未授权)

返回结果示例

{
    "costTime": 16,
    "errorCode": "0",
    "errorMsg": "success",
    "result": {
        "transId": "1524487322336",
        "udid": "0af2dc8a3a164f828b71cc5324c3880d"
    }
}
1
2
3
4
5
6
7
8
9

# STEP3:授权确认

HTTP Method:GET和POST
请求地址:http://product-auth.hivoice.cn/product-test/rest/v1/app_auth/confirm

参数 类型 必填 描述
transId String Y 当前事务时间戳(授权事务ID)
clientName String N 产品渠道
prodBatchCode String N 生产批次
appKey String Y appKey
udid String Y 授权码
sign String Y 签名串

返回值

参数 类型 必填 描述
errorCode String Y 响应code,成功为0,具体见错误码定义
errorMsg String Y 响应描述
costTime Integer Y 响应时间,单位:毫秒
result Object Y 返回的结果数据
└transId String Y 当前授权事务ID
└udid String Y 授权码(为空表示未授权)

返回结果示例

{
    "costTime": 16,
    "errorCode": "0",
    "errorMsg": "success",
    "result": {
        "transId": "1524487322336",
        "udid": "0af2dc8a3a164f828b71cc5324c3880d"
    }
}
1
2
3
4
5
6
7
8
9

# 签名规则

1)将格式化后的参数以字典序升序排列,拼接在一起,注意字典序中大写字母在前,空值(null)不参与签名;

注意:计算sign时所有参数也需要进行URLEncode;

如排序后的字符串为:A="transId=1524477063548&udid=21221c025e0846fb97bceb5b55d814ac"

2)将第一步中形成字符串进行BASE64编码;此时B=BASE64(A)

3)将第二步中形成字符串进行MD5加密,形成一个32位的十六进制字符串,即为本次请求sign(签名)的值;此时sign=md5(B)

然后再POST请求时,所有参数的值都应进行URLEncode;(参数值是数字或字母的可以不进行URLEncode)

该签名值基本可以保证请求是合法者发送且参数没有被修改,但无法保证不被偷窥。

# 签名示例

/**
* 签名算法
* 
* @param params
*            要参与签名的数据对象
* @return 签名
* @throws IllegalAccessException
*/
public static String getSign(Map<String, String> params) throws Exception {
    if (null == params || params.isEmpty() ) {
        return null;
    }
    params.remove("sign");
    // 格式化并排序请求参数
    String result = formatAndSortParams(params);
    // Base64编码
    result = CoderUtil.encryptBASE64(result).replace("\r\n", "");
    // MD5运算
    result = new String(DigestUtils.md5Hex(result));
    return result;
}	

/**
    * 格式化并排序请求参数
    * 
    * @param obj
    * @throws Exception
    * @return String
    * @throws
    *
    */
private static String formatAndSortParams(Map<String, String> map) throws Exception {
    if (null == map || map.size() == 0) {
        return null;
    }

    ArrayList<String> list = new ArrayList<String>();
    for (Map.Entry<String, String> entry : map.entrySet()) {
        if (StringHandler.isNullOrEmpty(entry.getKey()) || StringHandler.isNullOrEmpty(entry.getValue())) {
            continue;
        }
        list.add(entry.getKey().trim() + "=" + UrlCoder.encode(entry.getValue().trim()) + "&");
    }
    int size = list.size();
    String[] arrayToSort = list.toArray(new String[size]);
    Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < size; i++) {
        sb.append(arrayToSort[i]);
    }
    String params = sb.toString();

    if (params.endsWith("&")) {
        params = params.substring(0, params.length() - 1);
    }
    return params;
}
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

# 错误码定义及描述

errorCode errorMsg 描述
0 请求正常 成功
1001 不支持的服务 不支持的服务
1002 参数校验失败 包括参数缺失、参数格式错误等情况
1003 连接超时 连接超时
1004 读取数据超时 读取数据超时
1005 渠道授权数超限 渠道授权数超限
1006 该设备无授权记录 该设备无授权记录
1007 客户编码不存在 客户编码不存在
1012 调用设备中心返回数据为空或错误信息 调用设备中心返回数据为空或错误信息
1013 调用设备中心异常 调用设备中心异常
1014 应用不存在 应用不存在
9999 服务器内部异常 服务器内部异常