0

I am using the npm recaptcha verify plugin: https://www.npmjs.com/package/recaptcha-verify

In my react app I am using https://www.npmjs.com/package/react-google-invisible-recaptcha

At the top of my node app code:

var Recaptcha = require('recaptcha-verify');
var recaptcha = new Recaptcha({
    secret: 'secret_key',
    verbose: true
});

And then the route that works fine to send the email without recaptcha...

router.post('/mailer/recaptcha', function(req, res) {

   var userResponse = req.query['g-recaptcha-response'];
   console.log("user response: ", userResponse)

   recaptcha.checkResponse(userResponse, function(error, response){
       if(error){
        // an internal error? 
        res.status(400).render('400', {
            message: error.toString()
        });
        return;
    }
    if(response.success){
        res.status(200).send('the user is a HUMAN :)');
        // save session.. create user.. save form data.. render page, return json.. etc. 

    }else{
        res.status(200).send('the user is a ROBOT :(');
        // show warning, render page, return a json, etc. 
    }
});

In the form, using the react plugin, I am trying to follow the documentation as well, and it currently looks like this.

 <Recaptcha
  ref={ ref => this.recaptcha = ref }                                  
  sitekey="site_key"
  onResolved={ this.testRecaptcha } />

The onResolved function attempts to validate the Recaptcha. this.testRecaptcha is a function that dispatches to our node route as seen above. In that route, where I console.log the userResponse,, I am getting undefined. That appears to be the main issue here, I think. The req also logs out all of the items in my form as part of the req.body, but nothing indicates that the recaptcha field is actually there.

testRecaptcha(e) {

    let myObject = Object.assign({}, this.state.form, { sentFrom: 'contact', sendTo: this.state.sendTo });
    this.props.dispatch(actions.sendTestToMailer(myObject));
}

When I inspect the code that is output from the recaptcha component it looks like this:

<div style="display: none;"><div class="grecaptcha-badge" style="width: 256px; height: 60px; transition: right 0.3s ease; position: fixed; bottom: 14px; right: -186px; box-shadow: gray 0px 0px 5px;"><div class="grecaptcha-logo"><iframe src="https://www.google.com/recaptcha/api2/anchor?k=sitekey&amp;co=aHR0cDovL2xvY2FsaG9zdDo4MDgx&amp;hl=en&amp;v=v1514934548259&amp;size=invisible&amp;cb=oh5n23icp55m" width="256" height="60" role="presentation" frameborder="0" scrolling="no" sandbox="allow-forms allow-popups allow-same-origin allow-scripts allow-top-navigation allow-modals allow-popups-to-escape-sandbox"></iframe></div><div class="grecaptcha-error"></div><textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px; height: 40px; border: 1px solid #c1c1c1; margin: 10px 25px; padding: 0px; resize: none;  display: none; "></textarea></div></div>

(where sitekey is the actual key -- not the text 'sitekey)

but, i receive the following error from the node.js app

{ success: false, 'error-codes': [ 'invalid-input-response' ] }

It seems I am not pushing the recaptcha data into this.state.form, but I am not sure what object needs to be pushed into that or if that is even the issue.

Does anyone have any insight on this? Is there an easier way to verify the invisible recaptcha? There is little to no documentation or working examples with every step to take here with node and react. Hopefully someone can help me and anyone else in a similar situtation?

------- EDIT -------------------------------------------------------

Based on feedback from trixn, made these changes and its almost working...

testRecaptcha(e) {

        let recaptchaResponse = this.recaptcha.getResponse();

        let myObject = Object.assign({}, this.state.form, { sentFrom: 'contact', sendTo: this.state.sendTo, recaptchaResponse:recaptchaResponse });
        this.props.dispatch(actions.sendTestToMailer(myObject));
    }

AND...

in the node backend:

var userResponse = req.body.recaptchaResponse;

recaptcha.checkResponse(userResponse, function(error, response){ etc..});

but... I am now getting this error. Error parsing the response to an object. AND 'No default engine was specified and no extension was provided.'

Starfs
  • 412
  • 1
  • 5
  • 18

1 Answers1

1

You need to get the response token of your solved reCaptcha by accessing this.recaptcha.getResponse() in your onResolved callback then add that to your POST data and validate that in your node backend.

trixn
  • 15,761
  • 2
  • 38
  • 55
  • This is definitely necessary. Thank you. It is now coming through on the node.js side. I now get a long string key as the response and when I test it within recaptcha.checkResponse(userResponse, function(error, response){}); It gives me this respons here: CAPTCHA > error parsing: { success: true, challenge_ts: '2018-01-18T20:45:44Z', hostname: 'localhost' } but then i get an error: Error parsing the response to an object. and .. No default engine was specified and no extension was provided. Any ideas? – Starfs Jan 18 '18 at 20:51