sms 是短消息的意思,这部分主要讲的是如何使用 nodejs 完成 sms 相关业务
你总能找个理由,必须用 sms,因为这样你就可以拿到手机号,各种运营手段,数据价值,此处就不八卦了。
我其实找了很多,有的太烂,有的不敢信,有的界面太丑。。。最后选了 luosimao,并写一个 node 模块
它的好处
node-sms-luosimao 是 node 发送短信模块,后台服务采用的是 luosimao.com 的服务
npm install --save node-sms-luosimao
var sms = require("./index");
sms.key = process.env.LSM_KEY
sms.send('18612189310', '测试1~~【node发送短信模块】', function(error, res, body){
console.log(body);
});
说明
OTP 全称叫 One-time Password,也称动态口令,是根据专门的算法每隔 60 秒生成一个与时间相关的、不可预测的随机数字组合,每个口令只能使用一次,每天可以产生 43200 个密码。
它分 2 钟
对于短信码这种需求,哪种都可以的,如果是 60s 内不允许重新生成,totp 就足够了。
下面给出具体实现,参见https://github.com/guyht/notp
var notp = require('notp');
var opt = {
window : 0,
};
var app = {
encode: function(key) {
// make sure we can not pass in opt
return notp.totp.gen(key, opt);
},
decode: function(key, token) {
var login = notp.totp.verify(token, key, opt);
// invalid token if login is null
if (!login) {
console.log('Token invalid');
return false;
}
// valid token
// console.log('Token valid, sync value is %s', login.delta);
return true;
}
}
module.exports = app;
在这里我写了一个 encode 和 decode 方法,即采用 totp 加解密,核心参数是 key。
那么 key 怎么能保证唯一呢?其实很简单,我们的业务一般是根据手机号或用户绑定的,所以就很简单了。
短信发送是按条收费的,不能乱发,那都是钱啊,于是有了各种限制,比如常见的 60s 内可以再发一次。每次验证码的有效期是 10 分钟或者其他时间。
那么这些规则怎么实现更好呢?
最简单也是最好的办法是利用 redis 的 expire 命令
http://redis.io/commands/expire
expire 命令的原理是在 redis 里设置 key 的是 value,从设置开始,xx 秒之后,这个 key 就会被删除掉
这样做的好处:
实现如下:
var redis = require('redis')
, client = redis.createClient();
client.on('error', function (err) {
console.log('Error ' + err);
});
client.on('connect', function(){
});
function cache_expire(k, v){
console.log('============= cache_expire ==============');
if(client){
client.set(k, v, redis.print);
// Expire in 1*60 seconds
client.expire(k, 1*60);
}else{
console.log('redis client instance is not exist.');
}
}
/* GET home page. */
router.get('/request_verify_token', function(req, res) {
var tel = req.param('tel')
var key = tel + '123456789ssdsfx01234567890';
a = opt.encode(key);
console.log(a);
//首先检测缓存里是否有tel的key
client.get(tel, function (err, reply) {
if(reply) {
console.log('已存在: 不做任何处理' + reply.toString());
res.status(200).json({
code: 1,
msg:'fail,最近1分钟内会已有申请,不允许重复操作'
})
} else {
console.log('不存在,发送短信');
sms.send(tel, a + '(xxx验证码),请尽快完成验证。' + '~~【xxxxx】', function(error, response, body){
console.log(body);
if(error){
res.status(200).json({
code: 1,
msg:'sms.send fail'
})
}else{
cache_expire(tel, a);
res.status(200).json({
code: 0,
msg:'sms.send sucess'
})
}
});
}
});
});
说明
其他逻辑和这个类似,自己实现。
业务系统和 sms 系统是分开的,如果并发非常高
全文完
欢迎关注我的公众号【node 全栈】
ruby 里海波写的短信的 gem 很不错