reCAPTCHA - коды ошибок: «missing-input-response», «missing-input-secret» при проверке ответа пользователя (недостающие детали в POST) - PullRequest
0 голосов
/ 20 сентября 2018

Я устанавливаю невидимое reCAPTCHA в моем веб-приложении и испытываю проблемы с проверкой ответа пользователя.(хотя я передаю правильные параметры POST)

Я программно вызываю вызов, вызывая grecaptcha.execute(); на стороне клиента.И после отправки формы (registrationForm.submit();) с помощью обратного вызова recaptcha:

<div class="g-recaptcha"
  data-sitekey="SITE_KEY"
  data-callback="onSubmit"
  data-size="invisible">
</div>

Теперь, прочитав «Проверка ответа пользователя» документацию, я понял, чтотокен ответа передается в качестве параметра POST g-recaptcha-response:

Для пользователей сети вы можете получить токен ответа пользователя одним из трех способов:

  • gПараметр POST -recaptcha-response, когда пользователь отправляет форму на ваш сайт
  • ...

Поэтому я использую Fetch для созданияPOST-запрос на стороне сервера к конечной точке проверки с необходимыми данными тела:

verify(req, res, next) {
  const VERIFY_URL = "https://www.google.com/recaptcha/api/siteverify";

  return fetch(VERIFY_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      secret:   process.env.RECAP_INVIS_SECRET_KEY,
      response: req.body['g-recaptcha-response'],
    }),
  })
  .then(response => response.json())
  .then(data => {
    res.locals.recaptcha = data;
    return next();
  });
}

Но я получаю следующий ответ:

{success: false, коды ошибок: ['missing-input-response', 'missing-input-secret']}

Несмотря на то, что я передаю ответ и секрет в виде данных JSON в теле POST.

Я что-то не так делаю?С уважением.

1 Ответ

0 голосов
/ 20 сентября 2018

Проведя небольшое исследование и покопавшись на reCaptcha форумах Google , похоже, что эта конечная точка принимает только тип контента по умолчанию;application/x-www-form-urlencoded.

Это означает, что вы должны не использовать JSON для отправки своего токена ответа и ключа сайта.Вместо этого отправьте значение в виде, как определено application/x-www-form-urlencoded:

Формы, отправленные с этим типом содержимого, должны быть закодированы следующим образом:

  1. Имена и значения элементов управления экранированы.Пробельные символы заменяются на «+», а затем зарезервированные символы экранируются, как описано в [RFC1738], раздел 2.2: не буквенно-цифровые символы заменяются на «% HH», знак процента и две шестнадцатеричные цифры, представляющие код ASCIIперсонаж.Разрывы строк представляются в виде пар «CR LF» (т. Е. «% 0D% 0A»).
  2. Имена / значения элементов управления перечислены в порядке их появления в документе.Имя отделяется от значения символом '=', а пары имя / значение отделяются друг от друга знаком '&'.

Таким образом, у вас есть два способа сделать это:передача параметров POST через URL (строки запроса) и отправка его в виде запроса POST:

https://www.google.com/recaptcha/api/siteverify?secret=${SECRET_KEY}&response=${req.body['g-recaptcha-response']}

или добавление данных в тело вручную, например:

verify(req, res, next) {
  const VERIFY_URL = "https://www.google.com/recaptcha/api/siteverify";

  return fetch(VERIFY_URL, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: `secret=${SECRET_KEY}&response=${req.body['g-recaptcha-response']}`,
  })
  .then(response => response.json())
  .then(data => {
    res.locals.recaptcha = data;
    return next();
  });
}
...