物联网平台提供云端管理产品、设备、分组、Topic、规则、设备影子等API接口,和从云端发布消息的API接口。使用云端SDK,向API的服务端地址发送HTTPS/HTTP GET或POST请求,并按照API接口说明,在请求中加入相应请求参数来调用API。物联网平台根据请求的处理情况,返回处理结果。
api接口列表参考文档:
https://help.aliyun.com/document_detail/69893.html
公共参数说明参考文档:
https://help.aliyun.com/document_detail/30561.html
签名机制参考文档:
https://help.aliyun.com/document_detail/30563.html
签名机制文档中提供一个java版的签名demo,未提供其他语言的,下面是我实现的js版签名过程。
const crypto = require('crypto'); const urlencode = require('urlencode'); const moment = require("moment"); function timestamp() { var date = new Date(); var time = moment(date).utcOffset(0).format("YYYY-MM-DDTHH.mm.ss"); time += 'Z'; console.log("date===" + date); console.log("time===" + time); // 删除掉毫秒部分 return time; } function encode(str) { var result = urlencode(str, "utf8"); return result.replace(/!/g, '%21') .replace(/'/g, '%27') .replace(/\(/g, '%28') .replace(/\)/g, '%29') .replace(/\*/g, '%2A'); } function replaceRepeatList(target, key, repeat) { for (var i = 0; i < repeat.length; i++) { var item = repeat[i]; if (item && typeof item === 'object') { const keys = Object.keys(item); for (var j = 0; j < keys.length; j++) { target[`${key}.${i + 1}.${keys[j]}`] = item[keys[j]]; } } else { target[`${key}.${i + 1}`] = item; } } } function flatParams(params) { var target = {}; var keys = Object.keys(params); for (let i = 0; i < keys.length; i++) { var key = keys[i]; var value = params[key]; if (Array.isArray(value)) { replaceRepeatList(target, key, value); } else { target[key] = value; } } return target; } function normalize(params) { var list = []; var flated = flatParams(params); var keys = Object.keys(flated).sort(); for (let i = 0; i < keys.length; i++) { var key = keys[i]; var value = flated[key]; list.push([encode(key), encode(value)]); } return list; } function canonicalize(normalized) { var fields = []; for (var i = 0; i < normalized.length; i++) { var [key, value] = normalized[i]; fields.push(key + '=' + value); } return fields.join('&'); } var AccessKeyId = ""; var accessSecret = ""; /* var str = "POST&%2F&AccessKeyId%3D" + AccessKeyId + "%26Action%3DQueryDevice%26Format%3DJSON%26ProductKey%3Da1tDKl1PBkl%26RegionId%3Dcn-shanghai%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3D86439216304009%26SignatureVersion%3D1.0%26Timestamp%3D2021-12-28T06%253A37%253A48Z%26Version%3D2018-01-20";; */ var str = ""; var httpmethod = "POST"; var params = {}; params.Format = "JSON"; params.Version = "2018-01-20"; params.AccessKeyId = AccessKeyId; params.SignatureMethod = "HMAC-SHA1"; //params.Timestamp = timestamp(); params.Timestamp = '2021-12-28T06:37:48Z'; params.SignatureVersion = "1.0"; params.SignatureNonce = "86439216304009"; params.Action = "QueryDevice"; params.ProductKey = "a1tDKl1PBkl"; params.RegionId = "cn-shanghai"; var normalized = normalize(params); console.log("normalized===" + normalized); var canonicalized = canonicalize(normalized); console.log("canonicalized===" + canonicalized); str = httpmethod + "&" + encode("/") + "&" + encode(canonicalized); console.log("str===" + str); var key = accessSecret + "&"; const signature = Buffer.from(crypto.createHmac('sha1', key).update(str).digest()).toString('base64'); console.log("signature==="+signature); console.log("最终signature===" + encode(signature));