与 passport.js 一起验证验证码

Validating captcha along with passport.js

是否可以在调用passport.js authenticate函数之前验证google recaptcha是否成功?

我在二选一之间犹豫不决,因为两者都使用异步回调来验证,我不能将它们放在一起。

    function verifyRecaptcha(key, rq, rs, pa, callback) {
    https.get('https://www.google.com/recaptcha/api/siteverify?secret=' + SECRET + '&response=' + key, function (res) {
        var data = '';
        res.on('data', function (chunk) {
            data += chunk.toString();
        });
        res.on('end', function () {
            try {
                var parsedData = JSON.parse(data);
//                    return true;
                callback(parsedData.success, rq, rs, pa);
            } catch (e) {
//                    return false;
                callback(false, rq, rs, pa);
            }
        });
    });
}

    app.post('/auth/signin', can_access.if_not_logged_in(), passport.setupLocalStrategy(),
    function (req, res) {
        console.log('HERE');

        verifyRecaptcha(req.body['g-recaptcha-response'], function (success) {
            if (success) {
                // find a way to signal captcha succeeded.
                return true;
            } else {
                res.end('Captcha failed, sorry.');
                // TODO: take them back to the previous page
                // and for the love of everyone, restore their inputs
                return false;
            }
        });
    },
    passport.authenticate('local', {
        successRedirect: '/',
        failureRedirect: 'auth/signin',
        failureFlash: true
    }));

我想验证码成功后进行认证

Express 中间件或路由处理程序的工作方式是它们是连续执行的,一个接一个,只要前一个调用 next()

所以你只需要从你的验证码验证中间件调用next(),这样你接下来的passport.authenticate中间件就可以执行了。

此外,如果您调用 next(err)(即向其传递错误),它将跳过所有中间件并直接转到下一个具有 4 个参数签名 (err, req, res, next) 的中间件,这通常是主要错误处理程序位于 routes/middlewares 的末尾或附近。

所以只需尝试将您的代码更改为:

app.post('/auth/signin', can_access.if_not_logged_in(), passport.setupLocalStrategy(),
function (req, res, next) { // <<-- 1. have next passed here
    console.log('HERE');

    verifyRecaptcha(req.body['g-recaptcha-response'], function (success) {
        if (success) {
            // find a way to signal captcha succeeded.
            return next(); // <<-- 2. call next(); 
        } else {
            res.end('Captcha failed, sorry.');
            // TODO: take them back to the previous page
            // and for the love of everyone, restore their inputs
            return false;
        }
    });
},
// this will only be invoked if next() was called from previous middleware 
passport.authenticate('local', {
    successRedirect: '/',
    failureRedirect: 'auth/signin',
    failureFlash: true
}));