密码恢复时的节点睡眠命令 - 防止帐户收集

Node Sleep Command On Password Recovery - Prevent Account Harvesting

我有非常通用的密码恢复代码,它要求提供电子邮件,如果电子邮件存在则发送密码 link,如果不存在则打印一条消息。我想阻止人们试图有效地收集帐户数据。我的理解是,由于 Node 是单线程的,因此睡眠会阻止所有其他操作。什么是延长获取用户详细信息的操作的好方法(喜欢整整一秒)。

app.post('/login/recover', function(req, res, next) {
    async.waterfall([
        function(done) {
            // generate hash here
        },
        function(token, done) {
            var genReset = function(user) {
                if (!user) {
                    // SLEEP HERE!?!?!?
                    req.flash('failureMessage', 'No account with that email address exists.');
                    return res.redirect('/login/recover');
                }
                user.resetPasswordToken = token;
                user.resetPasswordExpires = moment().add(1, 'hours').format(); // 1 hour
                //save user here
            }
            user_manager.getUserForEmail(req.body.email, genReset);
        },
        function(token, user, done) {
            // email here
            req.flash('successMessage', 'Password link sent!');
            done(null, 'done');
        }
    ], function(err) {
        if (err) {
            return next(err);
        }
        res.redirect('/login/recover');
    });

});

我假设您正试图阻止人们过于频繁地访问您的端点。单靠睡眠是做不到这一点的。攻击者可以简单地打开数百个并行请求。

最好通过 IP 地址限制对端点的访问。保留 IP 地址的映射(js 对象)和每个地址访问端点的次数。如果 IP 地址多次访问端点,请禁用对该 IP 地址的访问。每隔几个小时将对象和计数器重置为 0。

如果您仍想实现睡眠,那么一般模式是使用 setTimeout 调用。

function(done) {
  var dosomething = function() {
    //do something here
    done();
  };
  setTimeout(dosomething, 1000);
};