1. 程式人生 > >手機驗證簡訊設計與程式碼實現

手機驗證簡訊設計與程式碼實現

總體思路
  1. 時效限制: [5-10min]
  2. 使用次數限制: 1次
  3. IP次數限制: 防止惡意刷手機驗證碼簡訊
  4. 手機號限制: 防止簡訊轟炸
  5. 跨域請求限制: 進一步限制惡意刷簡訊
  6. 驗證碼驗證: 進一步限制惡意刷簡訊
資料庫設計 (CheckCode)

ID mobile(手機號) 
checkCode(驗證碼) 
ip(IP地址) 
createAt(建立時間) 
expireAt(時效時間) 
isUse(是否使用) 
usingAt(使用時間)

具體程式碼實現(mongoose + nodejs 程式碼不完全正確,主要see思路吧)
  1. 查詢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); } }
  1. 查詢手機號碼接收次數,如果太多明顯要轟炸別人,讓我們背黑鍋呀
    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()  //
        }
    });
  1. 查詢這個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);
    }
  1. 限制跨域提交
 //渲染頁面時
 var oldCrsf = "12345679";
 req.session._csrf = oldCrsf;

 //接受提交
 var _crsf = req.body._crsf;
 if (_crsf !== req.session._csrf) {
    res.send(302);
 } else {
    // ok
 }
  1. 驗證碼限制 (同跨域提交思路)