web-dev-qa-db-fra.com

Comment vérifier la réponse de Google Recaptcha V3

Comment intégrer Google reCAPTCHA Version 3 dans les environnements client et serveur (php). le code suivant utilise pour afficher recaptcha mais cela ne fonctionne pas bien. Comment faire cette intégration.

<html>

<head>
  <script src='https://www.google.com/recaptcha/api.js?render=XXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'></script>
</head>

<body>
  <script>
    grecaptcha.ready(function() {
      grecaptcha.execute('XXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', {
        action: 'action_name'
      });
    });
  </script>

  <form action="verify.php" method="post">
    <input type="text" name="name" placeholder="Your name" required>
    <input type="email" name="email" placeholder="Your email address" required>
    <textarea name="message" placeholder="Type your message here...." required></textarea>

    <input type="submit" name="submit" value="SUBMIT">

  </form>

</body>

</html>

Verify.php

<?php

    if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])) {
        //your site secret key
        $secret = 'XXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
        //get verify response data
        $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']);
        $responseData = json_decode($verifyResponse);
        if($responseData->success):

             print_r("Working Fine"); exit;
        else:
             print_r("No valid Key"); exit;
        endif;
    } else {
        print_r("Not Working Captcha"); exit;
    }

?>
27
Karthik
<html>
    <head>
        <script src='https://www.google.com/recaptcha/api.js?render=6Le7-FkUAAAAADDSsTVBvpoUB5MkesNKgPVemFf-UD'></script>
    </head>
    <body> 
    <script>
    // when form is submit
    $('form').submit(function() { 
        // we stoped it
        event.preventDefault();
        // needs for recaptacha ready
        grecaptcha.ready(function() {
            // do request for recaptcha token
            // response is promise with passed token
            grecaptcha.execute('6Le7-FkUAAAAADDSsTVBvpoUB5MkesNKgPVemFf-UD', {action: 'create_comment'}).then(function(token) {
                // add token to form
                $('form').prepend('<input type="hidden" name="token" value="' + token + '">');
                $('form').prepend('<input type="hidden" name="action" value="create_comment">');
                // submit form now
                $('form').unbind('submit').submit();
            });;
        });
    });

    </script>

    <form action="verify.php" method="post">
        <input type="text" name="name" placeholder="Your name" required >
        <input type="email" name="email" placeholder="Your email address" required>
        <textarea name="message" placeholder="Type your message here...." required></textarea>   

        <input type="submit" name="submit" value="SUBMIT">

    </form>

    </body>

</html>

php

$token = $_POST['token'];
$secret = 'ur secret';
$action = $_POST['action'];
// now you need do a POST requst to google recaptcha server.
// url: https://www.google.com/recaptcha/api/siteverify.
// with data secret:$secret and response:$token 

À ce stade du code, vous devrez faire une demande de publication auprès de ReCAPTCHA pour vérifier le jeton, comme documenté ici: https://www.google.com/recaptcha/api/siteverify . La réponse sera un objet JSON avec le champ "succès" (vrai/faux) et "action" pour la comparaison (==) et le score (nombre compris entre 0.0 et 1.0).

https://developers.google.com/recaptcha/docs/v3#api-response .

Vous pouvez également spécifier le nom de l'action pour chaque demande (create_post, update_post, create_comment ...).

13
bsbak

Essaye ça.

<script>
  grecaptcha.ready(function() {
   grecaptcha.execute('<site-secret>', {action: 'MyForm'})
   .then(function(token) {
    console.log(token)
    document.getElementById('g-recaptcha-response').value =    token;
   }); 
  }); 
 </script> 

<form action="verify.php" method="post">
  <input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
  <input type="text" name="name" placeholder="Your name" required >
  <input type="email" name="email" placeholder="Your email address" required>
  <input type="submit" name="submit" value="SUBMIT" >
</form>
13
Bob

Voici un exemple de code de travail avec la démo.

code côté html

<html>
  <head>
    <title>Google recapcha v3 demo - Codeforgeek</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script src="https://www.google.com/recaptcha/api.js?render=put your site key here"></script>
  </head>
  <body>
    <h1>Google reCAPTHA Demo</h1>
    <form id="comment_form" action="form.php" method="post" >
      <input type="email" name="email" placeholder="Type your email" size="40"><br><br>
      <textarea name="comment" rows="8" cols="39"></textarea><br><br>
      <input type="submit" name="submit" value="Post comment"><br><br>
    </form>
      <script>
       // when form is submit
    $('#comment_form').submit(function() {
        // we stoped it
        event.preventDefault();
        var email = $('#email').val();
        var comment = $("#comment").val();
        // needs for recaptacha ready
        grecaptcha.ready(function() {
            // do request for recaptcha token
            // response is promise with passed token
            grecaptcha.execute('put your site key here', {action: 'create_comment'}).then(function(token) {
                // add token to form
                $('#comment_form').prepend('<input type="hidden" name="g-recaptcha-response" value="' + token + '">');
                    $.post("form.php",{email: email, comment: comment, token: token}, function(result) {
                            console.log(result);
                            if(result.success) {
                                    alert('Thanks for posting comment.')
                            } else {
                                    alert('You are spammer ! Get the @$%K out.')
                            }
                    });
            });;
        });
  });
  </script>
  </body>
</html>

Code PHP.

<?php

        $email;$comment;$captcha;
        if(isset($_POST['email'])){
          $email=$_POST['email'];
        }if(isset($_POST['comment'])){
          $comment=$_POST['comment'];
        }if(isset($_POST['token'])){
          $captcha=$_POST['token'];
          }
        if(!$captcha){
          echo '<h2>Please check the the captcha form.</h2>';
          exit;
        }
        $secretKey = "put your secret key here";
        $ip = $_SERVER['REMOTE_ADDR'];

        // post request to server

        $url =  'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($secretKey) .  '&response=' . urlencode($captcha);
        $response = file_get_contents($url);
        $responseKeys = json_decode($response,true);
        header('Content-type: application/json');
        if($responseKeys["success"]) {
                echo json_encode(array('success' => 'true'));
        } else {
                echo json_encode(array('success' => 'false'));
        }
?>

Cela fonctionne bien.

Démo: https://demo.codeforgeek.com/recaptcha-v3/

tutoriel: https://codeforgeek.com/2019/02/google-recaptcha-v3-tutorial/

3
Shaikh Shahid

Exemple simple de formulaire de contact vérifié par Google reCAPTCHA v3 avec JavaScript et PHP purs

tldr; passez au code en bas.

Documents reCAPTCHA pertinents, etc.:

(Si Google écoute, nous aimons votre travail et ce serait merveilleux d'avoir des exemples plus élaborés liés aux pages ci-dessus, s'il vous plaît.)

Vue d'ensemble:

  1. Obtenir les clés de Google
  2. Charger recaptcha/api.js dans la tête de html
  3. Soumission de formulaire de piratage avec JavaScript et à ce moment-là obtenir un jeton de Google
  4. Envoyer le formulaire avec jeton sur votre serveur
  5. Faites une demande à Google afin de vérifier la soumission du formulaire.
  6. Interpréter la réponse et procéder si nécessaire

Important à noter: le paramètre de réponse 'succès' indique uniquement si le captcha a été évalué avec succès, il n'indique pas si la soumission était susceptible de être un spam ou non.

Le paramètre "score" est le résultat que vous devez connaître. Plus le score est élevé (un nombre compris entre 0 et 1), plus une soumission est susceptible d'être authentique et il vous appartient de choisir le seuil (par exemple, 0,5) à accepter.

En détail:

Ajoutez la ligne suivante à la tête de votre code HTML pour charger le code recaptcha api.js:

<script src="https://www.google.com/recaptcha/api.js?render=$reCAPTCHA_site_key"></script>

(où $reCAPTCHA_site_key représente votre "clé de site" publique, que j'ai enregistrée dans un fichier "config.php".)

Vous devez soumettre un jeton (fourni par Google et propre à chaque soumission de formulaire) sur votre serveur. Je pense que c'est plus simple de l'envoyer via POST avec le reste des données du formulaire. À cette fin, j'inclus un champ masqué dans le formulaire comme suit:

<form id="contactForm" method="post" action="contact">
    <!-- other form inputs -->
    <input type="hidden" id="gRecaptchaResponse" name="gRecaptchaResponse">
    <input type="submit" name="contact_submit" value="Send message">
</form>

(Nb. "Contact" est contact.php, mais j'ai "réécrit" l'URL avec .htaccess)

Nous devons maintenant pirater la soumission de formulaire par défaut pour générer le jeton. Nous pourrions générer le jeton au chargement de la page, mais comme celui-ci n’est valable que pendant deux minutes (si je lis correctement la page https://developers.google.com/recaptcha/docs/verify ) Je pense qu'il vaut mieux aller le chercher au moment de l'envoyer au serveur de votre site.

À cette fin, j'ai ajouté ce qui suit juste après la balise de formulaire de fermeture:

<script>
    contactForm.addEventListener('submit', event => {
        event.preventDefault()
        validate(contactForm)
    });
</script>

J'ai mis la fonction validate(form) juste avant la balise body de fermeture:

function validate(form) {
    //perform optional error checking on form. If no errors then request a token and put it into the hidden field
    getRecaptchaToken(form)
}

//some other (optional) form validation functions

function getRecaptchaToken(form) {
    grecaptcha.ready(function() {
        grecaptcha.execute($reCAPTCHA_site_key, {action: 'contactForm'}).then(function(token) {
            gRecaptchaResponse.value = token //set the value of the hidden field
            form.submit() //submit the form
        });
    });
}

Notes:

  • $reCAPTCHA_site_key est votre clé de site publique
  • action: 'contactForm' identifie la soumission de ce formulaire particulier dans le tableau de bord de Google reCAPTCHA, et il est recommandé de confirmer qu'il est conforme aux attentes dans le backend.

Dans le fichier principal PHP, lorsque la soumission du formulaire est reçue:

//get the IP address of the Origin of the submission
$ip = $_SERVER['REMOTE_ADDR'];

//construct the url to send your private Secret Key, token and (optionally) IP address of the form submitter to Google to get a spam rating for the submission (I've saved '$reCAPTCHA_secret_key' in config.php)
$url =  'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($reCAPTCHA_secret_key) . '&response=' . urlencode($g_recaptcha_response) . '&remoteip=' . urlencode($ip);

//save the response, e.g. print_r($response) prints { "success": true, "challenge_ts": "2019-07-24T11:19:07Z", "hostname": "your-website-domain.co.uk", "score": 0.9, "action": "contactForm" }
$response = file_get_contents($url);

//decode the response, e.g. print_r($responseKeys) prints Array ( [success] => 1 [challenge_ts] => 2019-07-24T11:19:07Z [hostname] => your-website-domain.co.uk [score] => 0.9 [action] => contactForm )
$responseKeys = json_decode($response, true);

//check if the test was done OK, if the action name is correct and if the score is above your chosen threshold (again, I've saved '$g_recaptcha_allowable_score' in config.php)
if ($responseKeys["success"] && $responseKeys["action"] == 'contactForm') {
    if ($responseKeys["score"] >= $g_recaptcha_allowable_score) {
        //send email with contact form submission data to site owner/ submit to database/ etc
        //redirect to confirmation page or whatever you need to do
    } elseif ($responseKeys["score"] < $g_recaptcha_allowable_score) {
        //failed spam test. Offer the visitor the option to try again or use an alternative method of contact.
    }
} elseif($responseKeys["error-codes"]) { //optional
    //handle errors. See notes below for possible error codes
    //personally I'm probably going to handle errors in much the same way by sending myself a the error code for debugging and offering the visitor the option to try again or use an alternative method of contact
} else {
    //unkown screw up. Again, offer the visitor the option to try again or use an alternative method of contact.
}

Notes:

  • Voici les données qui figureront dans la réponse de Google (renvoyées sous forme d'objet JSON):

   {
     "success": true|false,      // whether this request was a valid reCAPTCHA token for your site
     "score": number             // the score for this request (0.0 - 1.0)
     "action": string            // the action name for this request (important to verify)
     "challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
     "hostname": string,         // the hostname of the site where the reCAPTCHA was solved
     "error-codes": [...]        // optional
   }
  • Ce sont les codes d'erreur possibles:
    • missing-input-secret: Le paramètre secret est manquant.
    • invalid-input-secret: le paramètre secret est invalide ou mal formé.
    • missing-input-response: Le paramètre de réponse est manquant.
    • invalid-input-response: le paramètre de réponse est invalide ou mal formé.
    • mauvaise demande: la demande est invalide ou mal formée.
    • timeout-or-duplicate: la réponse n'est plus valide; soit est trop vieux ou a été utilisé précédemment.

Mettre tous ensemble:

contact.php

<?php  //contact.php

    require_once('config.php');

    //do server-side validation of other form fields

    if (/*form has been submitted and has passed server-side validation of the other form fields*/) {
        $ip = $_SERVER['REMOTE_ADDR'];
        $url =  'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($reCAPTCHA_secret_key) . '&response=' . urlencode($g_recaptcha_response) . '&remoteip=' . urlencode($ip);
        $response = file_get_contents($url);
        $responseKeys = json_decode($response, true);

        if ($responseKeys["success"] && $responseKeys["action"] == 'contactForm') {
            if ($responseKeys["score"] >= $g_recaptcha_allowable_score) {
                //send email with contact form submission data to site owner/ submit to database/ etc
                //redirect to confirmation page or whatever you need to do
            } elseif ($responseKeys["score"] < $g_recaptcha_allowable_score) {
                //failed spam test. Offer the visitor the option to try again or use an alternative method of contact.
            }
        } elseif($responseKeys["error-codes"]) { //optional
            //handle errors. See notes below for possible error codes
            //(I handle errors by sending myself an email with the error code for debugging and offering the visitor the option to try again or use an alternative method of contact)
        } else {
            //unkown screw up. Again, offer the visitor the option to try again or use an alternative method of contact.
        }

        exit;

    } else { //(re)display the page with the form

        echo <<<_END

            <!DOCTYPE html>
            <html lang="en">
                <head>
                    <title>Contact | Your website</title>
                    <link rel="stylesheet" href="css/style.css">
                    <script src="https://www.google.com/recaptcha/api.js?render=$reCAPTCHA_site_key"></script>
                </head>
                <body>

                    <!-- header etc -->

                    <form id="contactForm" method="post" action="contact">
                        //other form inputs
                        <input type="hidden" id="gRecaptchaResponse" name="gRecaptchaResponse">
                        <input type="submit" name="contact_submit" value="Send message">
                    </form>
                    <script>
                        contactForm.addEventListener('submit', event => {
                            event.preventDefault()
                            validate(contactForm)
                        });
                    </script>

                    <!-- footer etc -->

                    <script>
                        function validate(form) {
                            //perform optional client-side error checking of the form. If no errors are found then request a token and put it into the hidden field. Finally submit the form.
                            getRecaptchaToken(form)
                        }

                        //some (optional) form field validation functions

                        function getRecaptchaToken(form) {
                            grecaptcha.ready(function() {
                                grecaptcha.execute($reCAPTCHA_site_key, {action: 'contactForm'}).then(function(token) {
                                    gRecaptchaResponse.value = token
                                    form.submit()
                                });
                            });
                        }
                    </script>
                </body>
            </html>

_END;

config.php

<?php //config.php

//other site settings

// Google reCAPTCHA v3 keys
// For reducing spam contact form submissions

// Site key (public)
$reCAPTCHA_site_key = 'N0t-a-real-0N3_JHbnbUJ-BLAHBLAH_Blahblah';

// Secret key
$reCAPTCHA_secret_key = 'N0t-a-real-0N3_i77tyYGH7Ty6UfG-blah';

// Min score returned from reCAPTCHA to allow form submission
$g_recaptcha_allowable_score = 0.5; //Number between 0 and 1. You choose this. Setting a number closer to 0 will let through more spam, closer to 1 and you may start to block valid submissions.
2
wkille

J'aimerais vous proposer un flux de travail complet pour intégrer recaptchav3 dans une solution MVC ASP.NET de base.

dans votre fichier appsettings.json:

  "RecaptchaSettings": {
    "Uri": "https://www.google.com/recaptcha/api/siteverify",
    "SecretKey": "your private key"
    "SiteKey": "your public key",
    "Version": "v3"
  }

à votre avis (syntaxe @razor):

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<script src="https://www.google.com/recaptcha/[email protected]("RecaptchaSettings")["SiteKey"]"></script>

    <script>
        grecaptcha.ready(function () {
            grecaptcha.execute('@Configuration.GetSection("RecaptchaSettings")["SiteKey"]',  { action: 'homepage' })
                .then(function (token) {

                    document.getElementById('g-recaptcha-response').value = token;
                });
        });
    </script>

et dans votre formulaire, mettez ceci:

<form action="/">
…
<input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
…

</form>

Je crée une méthode simple pour le gérer:

public async Task<bool> ChallengePassed(string uri, string gRecaptchaResponse, string secret)
        {

            var concUri = uri + "?secret=" + secret + "&response=" + gRecaptchaResponse;

            var request = new HttpRequestMessage(HttpMethod.Get, concUri);
            var res = await _Client.SendAsync(request);

            if (!res.IsSuccessStatusCode)
            {
                return false;
            }

            var data = await res.Content.ReadAsStringAsync();

            dynamic JSONdata = JObject.Parse(data);
            if (JSONdata.success != "true")
            {
                return false;
            }

            return true;
        }

        #endregion

        #region PRIVATE

        #endregion

        #endregion

        #endregion
    }

et simplement je l'ai appelé dans un contrôleur:

 //recaptcha validation

    bool isChallengeOk = await _CaptchaVerify.ChallengePassed(_Configuration.GetValue<string>("RecaptchaSettings:Uri"), Request.Form["g-recaptcha-response"], _Configuration.GetValue<string>("RecaptchaSettings:SecretKey"));

remarquez que je configure les paramètres d'entrée à partir de l'objet "_Configuration", qui représente une instance d'objet de paramètre de configuration dans Startup.cs. Vous pouvez transmettre manuellement des paramètres à la méthode.

Profitez-en

1
Giorgio C.