安服优物联云平台提供管理产品、设备、Topic、服务订阅等API接口,和从安服优物联云平台发布消息的API接口。使用安服优SDK,向API的服务端地址发送HTTPS/HTTP GET或POST请求,并按照API接口说明,在请求中加入相应请求参数来调用API。安服优物联云平台根据请求的处理情况,返回处理结果。
一、服务地址
二、身份验证参数
参数 | 说明 |
---|---|
accessKey | 加密Key值注册会员后在个人中心获取 |
sign | 签名 拼接见签名机制 |
timestamp | 时间戳(秒) |
三、签名机制
安服优物联云平台会对每个接口访问请求的发送者进行身份验证,所以无论使用HTTP还是HTTPS协议提交请求,都需要在请求中包含签名(sign)信息。 签名时,您需在安服优物联云管理后台个人中心页面查看您的账号的accessKey和secret,然后进行对称加密。其中,accessKey用于标识访问者身份;secret是用于加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密。
请按照下面的方法对请求进行签名:
- 构造规范化的请求字符串(Canonicalized Query String)。 排序参数。 按参数名的字典顺序,对请求参数进行排序,包括身份验证参数和所调用接口需要的自定义参数。 对参数名称和参数值进行URL编码。 使用UTF-8字符集按照RFC3986规则编码请求参数名和参数值。编码规则如下: 字符A~Z、a~z、0~9以及字符-、_、.、~不编码。 其它字符编码成%XY的格式,其中XY是字符对应ASCII码的16进制表示。例如英文的双引号”对应的编码为%22。 扩展的UTF-8字符,编码成%XY%ZA…的格式。 英文空格要编码成%20,而不是加号+。 该编码方式与application/x-www-form-urlencodedMIME格式编码算法相似,但又有所不同。 使用等号=连接编码后的请求参数名和参数值。 使用与号&连接编码后的请求参数。参数排序与步骤a的排序一致。 完成后,即获得规范化请求字符串(CanonicalizedQueryString)。
- 构造签名字符串。
- 计算HMAC值。
- 计算签名值。 按照Base64编码规则把步骤3中的HMAC值编码成字符串,即得到签名值(sign)。
- 添加签名。 将得到的签名值作为sign参数,按照RFC3986的规则进行URL编码后,再添加到请求参数中,即完成对请求签名的过程。
四、签名示例
以调用获取产品信息详情接口为例。假设您的accessKey=testAccessKey,productKey=testProductKey,secret=testSecret,timestamp=1602662308。 组成签名前的请求URL https://iot.afuiot.com:6101/product/v1/get?productKey=testProductKey&accessKey=testAccessKey×tamp=1602662308
计算得到待签名字符串 升序排序结果:{accessKey=testAccessKey,productKey=testProductKey,timestamp=1602662308} 拼接后的字符:accessKey=testAccessKey&productKey=testProductKey×tamp=1602662308&key=testSecret
计算签名值 加密后的签名:269356d1183b71b89acb9a6878993090
将签名作为sign参数加入到URL请求中,最后得到的URL为:
https://iot.afuiot.com:6101/product/v1/get?productKey=testProductKey&accessKey=testAccessKey×tamp=1602662308&sign=269356d1183b71b89acb9a6878993090五、Java代码示例
以下为签名的Java Demo供您参考。 ``` public class MD5Utils { private static final Logger LOGGER = LoggerFactory.getLogger(MD5Utils.class);
/**
- 参数签名加密
- @param parameters
- @param secret
@return */ public static String signRequest(TreeMap
parameters, String secret,String charset){
TreeMap
treeMap = new TreeMap<>(new Comparator () { @Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}); treeMap = (TreeMap
) parameters; LOGGER.debug(“升序排序结果:”+treeMap); StringBuffer sb = new StringBuffer(); //把map中的集合拼接成字符串 for(Map.Entry entry:treeMap.entrySet()){ String key = entry.getKey();
Object value = entry.getValue();
sb.append(key).append("=").append(value).append("&");
} sb.append(“key”).append(“=”).append(secret); LOGGER.debug(“拼接后的字符:”+sb.toString()); //进行MD5加密 String sign = DigestUtils.md5Hex(getContentBytes(sb.toString(), charset)); LOGGER.debug(“加密后的签名:”+sign); return sign; } /**
- @param content
- @param charset
- @return
- @throws SignatureException
- @throws UnsupportedEncodingException
*/
private static byte[] getContentBytes(String content, String charset) {
if (charset == null || “”.equals(charset)) {
} try {return content.getBytes();
} catch (UnsupportedEncodingException e) {return content.getBytes(charset);
} } public static void main(String[] args) { TreeMapthrow new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
treeMap = new TreeMap<>(); treeMap.put(“accessKey”, “testAccessKey”); treeMap.put(“productKey”, “testProductKey”); treeMap.put(“timestamp”, String.valueOf(System.currentTimeMillis()/1000)); String secret = “testSecret”; MD5Utils.signRequest(treeMap,secret,”utf-8”); } } ```