最近公司使用nodejs调用阿里云短信接口发送短信,网上找了很多示例都不行,给的那些都不能正常使用。下面给出我调用成功的示例。
阿里云短信调用实质上就是构建一个http请求可以是post也可以是get,关键几个位置是域名、调用的方法,参数等几个东西,这几个东西对了以后调用就成功。
首先是域名,阿里云短信域名为http://dysmsapi.aliyuncs.com/,
之后是对应的参数,其它的参数都是比较简单的,关键的参数是Signature,Signature是签名参数,这个参数是根据构建的参数列表生成的,并且是唯一,每次调用都要重新生成。
第一步需要将对应的参数按着规则转为URI,第二步将URI使用hmac-sha1加密,然后转为base64第三步替换对应的特殊符合(这步有坑)。
第一步中需要注意的是Timestamp必须是东八区时区,不然会报过期的Timestamp参数、参数必须排序。第二步是调用系统内置的Hmac-sha1算法加密,没有啥注意的,顺序不错就好了。第三步,官网是把 + 替换成 %20,* 替换成 %2A,%7E替换成 ~,我替换+ 后会报签名算法不对,不知是不是算法规则改了。
下面给出具体示例:
var uuid = require('node-uuid'); var crypto = require('crypto'); var moment = require('moment'); var http = require('http'); var alidayuUrl = 'http://dysmsapi.aliyuncs.com/'; var OPAPI = require('opapi'); var config = { AppKey: 'your keyID', AppSecret: 'your keySecret' }; var obj = { AccessKeyId: config.AppKey, Action: 'SendSms', Format: 'JSON', PhoneNumbers: '', RegionId: 'cn-hangzhou', SignName: '麦杰科技', SignatureMethod: 'HMAC-SHA1', SignatureNonce: uuid.v1(), SignatureVersion: '1.0', TemplateCode: 'SMS_78610022', TemplateParam: '{"code":"123456"}', Timestamp: '', Version: '2017-05-25' } var sms = { NORMAL_TEMPPLATE: 'SMS_78770029', REGISTER_TEMPLATE: 'SMS_75995228', CHANGEPROJECT_TEMPLATE: 'SMS_75995226', FORGETPASSS_TEMPLATE: 'SMS_75995225', sendMessage: function (phone, TemplateCode, TemplateParam, callback) { var sendurl = this.url(phone, TemplateCode, TemplateParam); var req = http.request(sendurl, function (res) { var status = res.statusCode; if (status != 200) { callback(new Error('网络异常')); } res.setEncoding('utf8'); res.on('data', function (chunk) { var value = JSON.parse(chunk); if (value.Code != 'OK') { console.log(chunk); callback(new Error('短信发送异常')); } else { callback(null); } }).on('error', function (e) { callback(new Error('发送短信异常')); }); }); req.write('执行完毕'); req.end(); }, sign: function (params, accessSecret) { var param = {}, qstring = []; var oa = Object.keys(params); for (var i = 0; i < oa.length; i++) { param[oa[i]] = params[oa[i]]; } for (var key in param) { qstring.push(encodeURIComponent(key) + '=' + encodeURIComponent(param[key])); } qstring = qstring.join('&'); var StringToSign = 'GET' + '&' + encodeURIComponent('/') + '&' + encodeURIComponent(qstring); accessSecret = accessSecret + '&'; var signature = crypto.createHmac('sha1', accessSecret).update(StringToSign).digest().toString('base64'); signature = signature.replace(/\*/, '%2A').replace(/%7E/, '~'); return signature; }, url: function (phone, TemplateCode, TemplateParam) { var timestamp = moment(new Date().getTime() - 3600 * 1000 * 8).format("YYYY-MM-DDTHH:mm:ss") + 'Z'; obj.PhoneNumbers = phone; obj.SignatureNonce = uuid.v1(); obj.TemplateCode = TemplateCode; obj.TemplateParam = TemplateParam; obj.Timestamp = timestamp; var sign = this.sign(obj, config.AppSecret); var arr = []; for (var p in obj) { arr.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p])); } arr.push(encodeURIComponent('Signature') + '=' + encodeURIComponent(sign)) var msg = arr.join('&') var sendurl = alidayuUrl + '?' + msg; return sendurl; } } module.exports = sms;
上面的示例是今天刚跑通的示例,使用的时候只需要替换自己的对应的签名信息,模板编码等信息就可以。需要注意的地方已经在上面说了,如有不懂的地方可以留言。
https://help.aliyun.com/document_detail/56189.html?spm=5176.doc55288.6.562.D2yUYz
这个是阿里云官方给的解释和java生成签名的过程,其中的坑已经在上面说明了。
特别提示 参数排序,东八区时间,特殊字符替换
---------------------
作者:洪小灯
来源:CSDN
原文:https://blog.csdn.net/u012251421/article/details/75578370
版权声明:本文为博主原创文章,转载请附上博文链接!