Reputation: 1543
Is it possible to verify if google recaptcha succeeded before calling passport.js authenticate function?
I'm getting stuck between choosing one or the other because both use asynchronous callbacks to verify and I can't next them within each other.
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
}));
I want to do authentication after captcha has succeeded
Upvotes: 1
Views: 2217
Reputation: 34667
The way Express middlewares or route handlers work is that they are executed in succession, one after another, as long as the previous one called next()
So you just need to call next()
from your captcha verifying middleware so that your passport.authenticate
middleware which comes next can be executed.
Also, if you call next(err)
(i.e. passing it an Error) it will skip all the middlewares and go straight to the next middleware that has the 4 argument signature (err, req, res, next)
, which is usually the main error handler placed at or near the end in your routes/middlewares.
So simply try changing your code to this:
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
}));
Upvotes: 3