web-dev-qa-db-fra.com

reCAPTCHA - codes d'erreur: «réponse-entrée-manquante», «secret-entrée-manquante» lors de la vérification de la réponse de l'utilisateur (détails manquants sur POST)

Je mets un reCAPTCHA invisible dans mon application web et j'ai du mal à vérifier la réponse de l'utilisateur. (même si je passe les bons paramètres POST)

J'invoque le défi par programme en appelant grecaptcha.execute(); côté client. Et en soumettant le formulaire par la suite (registrationForm.submit();) en utilisant le rappel recaptcha:

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

Maintenant, après avoir lu la documentation "Vérification de la réponse de l'utilisateur" , je me suis dit que le jeton de réponse était transmis sous la forme d'un POST sur g-recaptcha-response:

Pour les utilisateurs Web, vous pouvez obtenir le jeton de réponse de l'utilisateur de trois manières:

  • g-recaptcha-response POST lorsque l'utilisateur soumet le formulaire sur votre site
  • ...

J'utilise donc Fetch pour créer une POST côté serveur au point final de vérification avec les données de corps requises:

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();
  });
}

Mais je reçois toujours la réponse suivante:

{succès: faux, codes d'erreur: ['réponse-entrée-manquante', 'secret-entrée-manquante']}

Même si je passe la réponse et le secret en tant que données JSON dans le corps POST.

Est-ce que je fais quelque chose de mal? Cordialement.

18
U-ways

Faire un peu de recherche et creuser autour des forums Google reCaptcha , Il semble que ce point final accepte uniquement le type de contenu par défaut; application/x-www-form-urlencoded .

Ce qui signifie que vous ne devez pas utiliser JSON pour envoyer votre jeton de réponse et votre clé de site. Envoyez plutôt la valeur comme la façon dont le application/x-www-form-urlencoded défini:

Les formulaires soumis avec ce type de contenu doivent être codés comme suit:

  1. Les noms et valeurs de contrôle sont échappés. Les caractères d'espace sont remplacés par "+", puis les caractères réservés sont échappés comme décrit dans [RFC1738], section 2.2: Les caractères non alphanumériques sont remplacés par "% HH", un signe de pourcentage et deux chiffres hexadécimaux représentant le ASCII du caractère. Les sauts de ligne sont représentés par des paires "CR LF" (c'est-à-dire, '% 0D% 0A').
  2. Les noms/valeurs de contrôle sont répertoriés dans l'ordre dans lequel ils apparaissent dans le document. Le nom est séparé de la valeur par '=' et les paires nom/valeur sont séparées les unes des autres par '&'.

Par conséquent, vous avez deux façons de procéder, soit en passant les paramètres POST via l'URL (chaînes de requête) et en l'envoyant sous la forme d'une requête POST:

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

ou en ajoutant manuellement les données au corps comme suit:

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();
  });
}
8
U-ways