手機驗證簡訊設計與程式碼實現
阿新 • • 發佈:2019-01-29
總體思路
- 時效限制: [5-10min]
- 使用次數限制: 1次
- IP次數限制: 防止惡意刷手機驗證碼簡訊
- 手機號限制: 防止簡訊轟炸
- 跨域請求限制: 進一步限制惡意刷簡訊
- 驗證碼驗證: 進一步限制惡意刷簡訊
資料庫設計 (CheckCode)
ID mobile(手機號)
checkCode(驗證碼)
ip(IP地址)
createAt(建立時間)
expireAt(時效時間)
isUse(是否使用)
usingAt(使用時間)
具體程式碼實現(mongoose + nodejs 程式碼不完全正確,主要see思路吧)
- 查詢90s內是否傳送過,如果存在,需要等待 90-(已傳送時間)s
var mobile = '155*****111',
ip = '127.0.0.1',
now = Date.now();
CheckCode.findOne({mobile: mobile, expireAt:{$gt: now}}, function(err, checkCode) {
if (err) {
//錯誤了
} else if(checkCode) {
var now = Date.now(),
diffSeconds = parseInt ((now - checkCode.createAt.getTime())/1000, 10);
if (diffSeconds < 90) {
//時間間隔太小,老弟你刷簡訊納是吧,果斷拒絕你
} else {
checkCode.setIsUsed(); //設定為已經使用過
newCheckCodeByMobile(mobile, {ip:ip}, done);
}
} else {
newCheckCodeByMobile(mobile, {ip:ip}, done);
}
}
- 查詢手機號碼接收次數,如果太多明顯要轟炸別人,讓我們背黑鍋呀
var end = now,
begin = now - 24 * 60 * 60 * 1000;
CheckCode.count({mobile: mobile, createAt: {$gt: begin, $lt: end}}, function(err, count){
if (err) {
//錯誤
} else if(count >3) {
//老大,都給你手機號發3次了還收不到,你是要用簡訊轟炸別人呢還是真收不到,果斷捨棄你這使用者把
} else {
newCheckCodeByMobile() //
}
});
- 查詢這個Ip傳送了多少次了, 如果太多明顯是來浪費我們財產來了,簡訊是要錢的呀老大
CheckCode.count({ip:ip, createAt: {$gt: begin, $lt: end}}, function(err, count){
if (err) {
//err
} else if (count >6) {
//老大,你這個Ip都浪費了我5毛錢了,你還不甘心呀,算了,放棄你了
} else {
newCheckCodeByMobile() //
}
});
//生成手機驗證碼
function newCheckCodeByMobile(mobile, options, callback) {
if (arguments.length === 2 ) {
callback = options;
options = {};
}
var ip = options.ip;
var now = Date.now(),
expireAt = now + 60 * 1000 * 5; //5分鐘後時效
CheckCode.save({mobile: mobile, ip:ip, checkCode:"123456", isUse:false}, callback);
}
- 限制跨域提交
//渲染頁面時
var oldCrsf = "12345679";
req.session._csrf = oldCrsf;
//接受提交
var _crsf = req.body._crsf;
if (_crsf !== req.session._csrf) {
res.send(302);
} else {
// ok
}
- 驗證碼限制 (同跨域提交思路)