11

I am really struggling to get a successful response when doing a post request to the google recaptcha api. I am receiving the following response:

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

I had a look at reCAPTCHA - error-codes: 'missing-input-response', 'missing-input-secret' when verifying user's response (missing details on POST) and followed the answer as closely as possible but with no success.

Here is my file below:

var request = require('request');

module.exports = {
  verifyCaptcha: function(req, res) {

    var secret = 'SECRET_KEY';
    var response = JSON.stringify(req.body.response);
    request({
        url: 'https://www.google.com/recaptcha/api/siteverify',
        method: 'POST',
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: `secret=${secret}&response=${response}`,
    }, function (err, response, body) {
        if (err) {
            res.status(500).send({
                error: "Could not verify captcha"
            });
        } else {
            res.status(200).send({
                message: body
            });
        }
    });
  },
}

If anyone has a solution to this problem please let me know!

hong4rc
  • 3,999
  • 4
  • 21
  • 40
Simon Jackson
  • 181
  • 1
  • 1
  • 7

4 Answers4

5

Due to the docs: https://developers.google.com/recaptcha/docs/verify

invalid-input-secret: The secret parameter is invalid or malformed. Maybe you have mixed the site_key and the secret_key.

Máté Gregor
  • 91
  • 1
  • 4
2

You need to add the user remote IP address.

var user_ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
request({
    url: 'https://www.google.com/recaptcha/api/siteverify',
    method: 'POST',
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: `secret=${secret}&response=${response}&remoteip=${user_ip}`}...

Another thing I see that you are not using template literal, you should change the quotes to ` instead of '.

OR, You should use a ready-made module for reCaptcha, like this one:

https://www.npmjs.com/package/recaptcha

arielb
  • 392
  • 3
  • 10
  • It doesn't really seem necessary to add a module for something like this though. Do you know why the above code doesn't work? – Simon Jackson Feb 14 '19 at 16:47
  • 2
    The remote IP thing is an [optional parameter](https://developers.google.com/recaptcha/docs/verify). I changed my quotes to ` but I'm still getting the same error. – Simon Jackson Feb 14 '19 at 17:01
  • 2
    You get "invalid-input-response", "invalid-input-secret", usually means that's something with your secret code isn't correct or you didn't get the input from the user. have you debugged it and see that you get a valid response input from the user? – arielb Feb 14 '19 at 17:05
  • I figured part of the problem, the response, `var response = JSON.stringify(req.body.response)` doesn't need to be stringified. So now the issue I'm getting is "invalid-input-secret". – Simon Jackson Feb 14 '19 at 17:12
  • what about your secret code? check again that you haven't misspelled it. – arielb Feb 14 '19 at 17:17
  • That's most of the cases :-) – arielb Feb 14 '19 at 17:27
  • Here's the updated solution to the problem: https://stackoverflow.com/a/66900684/11636916 – Sarthik Gupta Apr 01 '21 at 08:10
0

For reCAPTCHA Enterprise, check the official docs: https://cloud.google.com/recaptcha-enterprise/docs/create-assessment.

In short, you need to use the library that Google provides:

const { RecaptchaEnterpriseServiceClient } =
        require('@google-cloud/recaptcha-enterprise');

const client = new RecaptchaEnterpriseServiceClient();
const [ response ] = await client.createAssessment({...});

RecaptchaEnterpriseServiceClient requires a service account to be created beforehand as described here. The key for that account with the right roles set can then be read by the app. Check the arguments of the constructor to see the available options to pass the data if the file cannot be retrieved automatically.

Yuuhn
  • 1
  • 3
0
var response = JSON.stringify(req.body.response);

The stringifying here is probably the cause of the invalid-input-response error. If your body is something like {"g-recaptcha-response": "..."}, you need to pull out the response value and pass that directly in your post.

Regarding invalid-input-secret, if you have set up your key and secret through the classic interface at https://www.google.com/u/1/recaptcha/admin/create, then you shouldn't have a problem.
However if you set up a key with recaptcha Enterprise on Google Cloud, then it requires that you do Oauth authentication to the Google Cloud API and then use the create.assessment endpoint to get back information on the validity of the user. As Yuuhn implied, the Google provided library makes interaction with recaptcha Enterprise easier, without a lot of documentation digging to find where your REST API calls need to go.

Infineight
  • 498
  • 5
  • 10