应用开发指南及API
此部分的接口提供给北向开发者使用,以进行北向应用的开发。
开发者通过HTTP请求向IoT OS进行设备管理、数据管理和设备指令相关的请求,通过数据订阅获取设备的各种数据。
使用说明
IoT OS为接口访问提供了安全鉴权认证。开发者访问接口时需要在HTTP请求头中包含签名信息。
安全鉴权
IoT OS提供给用户AccessKey。 AccessKey由AccessKey ID和AccessKey Secret组成。AccessKey ID用于标识访问者身份,可以明文的形式传输。AccessKey Secret是用于加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密。
可以避免密钥在传输过程中泄露,且通过包含由非可逆算法生成的签名的token来进行身份认证,即使token被窃取,攻击者也无法通过token反向获得核心密钥。
鉴权参数token具有时间属性,IoT OS会计算token有效时间,可从时间维度降低被攻击/仿冒的风险。
获取AccessKey
登录Iot OS点击右上角"个人中心",选择"AccessKey"标签。
若未获取过AccessKey则点击右边"获取AccessKey"按钮。
【注意】 每个账号最多添加10个AccessKey。
使用AccessKey计算token
token参数组成
名称 | 类型 | 说明 | 示例 |
---|---|---|---|
accessKey | String | 用户的AccessKey ID,为由24位数字或字母组成。 | qzJ2UCE86Fd14hRG1LzrkT7w |
path | String | 用户发起请求的路径 | /addDevice |
timestamp | String | 数值为当前时间戳的长整型形式的字符串,时间戳单位为毫秒。 | 1575615530113 |
method | String | 加密方式,IoT OS使用的是HmacSHA1,此处写"SHA1"即可 | SHA1 |
sign | String | 通过AccessKey Secret与部分参数进行加密后的签名 | 具体计算方法见下详解 |
【注意】:
1.其中参数path
的格式为请求端口
与定界符?
之间的内容。
即
protocol://userInfo@host:port/path
?query#fragment
中高亮部分。
若请求有路径参数时也需要包含路径参数。
例:
http://localhost:8080/api/device/getDeviceHistoryData/9d7bc79042934535/Modb453543?page=0&size=10&startTime=1575993600000&endTime=1576166399999
其中path
值为/api/device/getDeviceHistoryData/9d7bc79042934535/Modb453543
。
2.token有效期为参数timestamp
时刻前后五分钟。
sign计算
首先对path、timestamp和method进行拼接得出data。拼接方式如下:
data = path + "\n" + timestamp + "\n" + method
使用HmacSHA1加密方式,使用AccessKey Secret作为密钥进行加密。
sign = HmacSHA1(data,accessKeySecret)
【注意】sign的计算结果要将字母保持为全小写。
token组合
计算出所有的参数后,按照顺序,使用"&"符号将参数连接。
【注意】path参数的数值需要进过URL编码。需要进行编码的特殊符号如下:
符号 | 编码 |
---|---|
+ | %2B |
空格 | %20 |
/ | %2F |
? | %3F |
% | %25 |
# | %23 |
& | %26 |
= | %3D |
token结果:
accessKey=qzJ2UCE86Fd14hRG1LzrkT7w&path=%2FaccessKey×tamp=1575652666325&method=SHA1&sign=58d5e5972e3d69c5da1867416726966182e73adb
token生成示例
public class Test {
private static final String MAC_NAME = "HmacSHA1";
public static byte[] HmacSHA1Encrypt(String encryptText, String encryptKey) throws Exception {
byte[] data = encryptKey.getBytes();
//根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称。
SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
//生成一个指定 Mac 算法 的 Mac 对象
Mac mac = Mac.getInstance(MAC_NAME);
//用给定密钥初始化 Mac 对象
mac.init(secretKey);
byte[] text = encryptText.getBytes();
//完成 Mac 操作
return mac.doFinal(text);
}
public static String parseByte2HexStr(byte[] buf) {
if (null == buf) {
return null;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString().toLowerCase();
}
public static String assembleToken(String path, String timestamp, String method, String accessKey, String accessSecret) throws Exception {
String encodePath = URLEncoder.encode(path, "UTF-8");
String data = path + "\n" + timestamp + "\n" + method;
String signature = parseByte2HexStr(HmacSHA1Encrypt(data, accessSecret));
return "accessKey=" +
accessKey +
"&path=" +
encodePath +
"×tamp=" +
timestamp +
"&method=" +
method +
"&sign=" +
signature;
}
public static void main(String[] args) throws Exception {
String path = "/addDevice";
String timestamp = String.valueOf(new Date().getTime());
String method = "SHA1";
String accessKey = "qzJ2UCE86Fd14hRG1LzrkT7w";
String accessSecret = "yeJEIAwLx0ezct1EK1hrbWOaAhuwAQ";
String token = assembleToken(path, timestamp, method, accessKey, accessSecret);
System.out.println("Authorization:" + token);
}
}
如何使用token
由上述计算得到token之后,在此后的API接口的http请求头中添加如下参数即可访问。
Headers:
参数名称 | 参数值 | 是否必须 |
---|---|---|
Authorization | {token} | 是 |
获取请求地址和端口
此模块所有的接口请求地址和端口,都可以在平台"产品开发"-选择产品-"产品概览"中的"应用接入信息中获取。如图所示。