API权限检验
一、消息体签名
消息体签名检验是开发者与 SENSORO IoT 云平台相互请求的鉴权方式。
开发者提交 Webhook(自定义回调URL) 地址后,SENSORO 发送给开发者的请求设置了 3 个 HTTP Header, 包括 X-ACCESS-ID
, X-ACCESS-NONCE
和 X-ACCESS-SIGNATURE
。开发者通过检验 signature 对请求进行校验, 来确认此次 POST 请求来自 SENSORO 服务器。
开发者请求 SENSORO IoT 开放 API 接口时,也需要携带以上三个 headers 参数,SENSORO 服务器通过检验 signature 对请求进行校验,来确定开发者身份。
请求携带 headers 参数如下表所示:
键名 | 名称 | 说明 |
---|---|---|
X-ACCESS-ID | AppID | 开发者应用标示符 |
X-ACCESS-NONCE | AppSecret | 发请求的 Unix 时间,精确到毫秒 |
X-ACCESS-SIGNATURE | 无 | 以 AppSecret 作为密钥,计算 X-ACCESS-NONCE + GET POST PUT DELETE... + 请求的完整 URL + 请求的 Body(无则留空{})的 HMAC(SHA256) 的结果。 |
开放 API 可使用 https://iot.sensoro.com “开发者” 页面内任意推送服务秘钥参数, 推送服务秘钥在系统中的位置如下图:
示例1, Webhook 接收端签名校验示例
NodeJS 示例:
var crypto = require('crypto'); var SECRET = "YOURAPPSECRET";
var error = new Error('Invalid signature'); error.status = 400;
function verifySignatrue(req) { var url = req.protocol + '://' + req.get('host') + req.originalUrl;
// 生成 ACCESS_NONCE,值为当前的 Unix 时间,单位为毫秒 var ACCESS_NONCE = req.headers['x-access-nonce'];
var BodyRaw = ''; if (req.body && req.body instanceof Object) { try{ BodyRaw = JSON.stringify(req.body); }catch(e) { console.error(e); } }
var original = new Buffer(ACCESS_NONCE + req.method.toUpperCase() + url + BodyRaw); var secret = crypto.createHmac('SHA256', SECRET).update(original).digest('base64');
if (req.headers['x-access-signature'] !== secret) { return callback(error); }
callback(); }
module.exports = function() {
return function(req, res, next) {
verifySignatrue(req, next);
};
};
</div></div>
示例2, Open API 获取传感器基本信息
NodeJS 示例:
var crypto = require('crypto'); var urllib = require('urllib'); var appID = '9yCs1XmRya2T'; var appSecret = 'MKLFSYfBgZJgdCNsN3xGdmKZBi6bRXi0';
function getDeviceInfo(callback) { var method = 'GET'; var nonce = 1500444830886; //Date.now(); var url = "https://iot-api.sensoro.com/developers/device/10900117C640F19D"; var signature = getSignature(appSecret, nonce, method, url, {}); var opt = { method: method, headers: { 'X-ACCESS-ID': appID, 'X-ACCESS-NONCE': nonce, 'X-ACCESS-SIGNATURE': signature }
}; urllib.request(url, opt, callback); }
function getSignature(appSecret, nonce, method, url, body){ var original = nonce + method + url + JSON.stringify(body); return crypto.createHmac('SHA256', appSecret) .update(new Buffer(original)).digest('base64'); }
getDeviceInfo(function(err, ret){
console.info(err, ret);
});
</div></div>
curl 示例:
curl -X GET 'https://iot-api.sensoro.com/developers/device/10900117C640F19D' -H 'x-access-id: 9yCs1XmRya2T' -H 'x-access-nonce: 1500444830886' -H 'x-access-signature: EBxaJU+SdbBKPfyqdlEY+9P0dN6VieuMUd/JGEwRbgo='
示例3, Open API 传感器传输周期设定
NodeJS 示例:
curl 示例:
curl -X POST 'https://iot-api.sensoro.com/developers/device/interval' -H 'x-access-id: 9yCs1XmRya2T' -H 'x-access-nonce: 1500444830886' -H 'x-access-signature: LrJg8MXMi5mCjzoiwOR1QuvZq6mp+6oVMtDBk5GQPs0=' -H 'content-type: application/json' -d '{"sns": ["10900117C640F19D"], "cfg": {"interval": 600 } }'
二、消息体加密
消息加密解密技术方案基于 AES 加解密算法来实现,具体如下:
- App Key 即消息加解密Key,长度固定为43个字符,从a-z,A-Z,0-9共62个字符中选取。由开发者在开发配置中填写,后也可修改。
- AES密钥: AESKey = Base64_Decode( AppKey + “=”),AppKey 尾部填充一个字符的 “=”, 用 Base64_Decode 生成 32 个字节的 AESKey;
- AES 采用 CBC 模式,秘钥长度为 32 个字节(256位),数据采用 PKCS#7 填充; PKCS#7:K 为秘钥字节数(采用32),buf 为待加密的内容,N 为其字节数。Buf 需要被填充为 K 的整数倍。在 buf 的尾部填充 (K-N%K) 个字节,每个字节的内容 是 (K- N%K)。
- BASE64 采用 MIME 格式,字符包括大小写字母各 26 个,加上 10 个数字,和加号 “+”,斜杠 “/”,一共 64 个字符,等号 “=” 用作后缀填充;
开发者可以下载开源的 NPM,安装使用,参考示例如下。