84 votes

Démonstration de l'exemple de Google Recaptcha v3

Jusqu'à présent, je travaillais avec Google Recaptcha v2, mais je veux maintenant mettre à jour ma WebApp en utilisant la dernière version (v3).

Est-il possible d'ajouter un exemple de Google Recaptcha v3 entièrement fonctionnel pour un formulaire de base, car je ne trouve aucune démonstration fonctionnelle ?

J'apprécierais vraiment.

Merci beaucoup.

PS : J'utilise des servlets Java du côté serveur, mais cela n'a pas d'importance si vous expliquez utiliser php ou autre.

2 votes

Voici le lien : recaptcha-demo.appspot.com Demandez simplement le score de la v3 et vous recevrez une réponse en JSON.

10 votes

J'ai créé une démo mais cela en PHP Visitez mon blog lien

0 votes

Mais comment puis-je mettre dans le div ?

113voto

kikerrobles Points 1083

Code simple pour implémenter ReCaptcha v3

Le code JS de base

<script src="https://www.google.com/recaptcha/api.js?render=your reCAPTCHA site key here"></script>
<script>
    grecaptcha.ready(function() {
    // do request for recaptcha token
    // response is promise with passed token
        grecaptcha.execute('your reCAPTCHA site key here', {action:'validate_captcha'})
                  .then(function(token) {
            // add token value to form
            document.getElementById('g-recaptcha-response').value = token;
        });
    });
</script>

Le code HTML de base

<form id="form_id" method="post" action="your_action.php">
    <input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
    <input type="hidden" name="action" value="validate_captcha">
    .... your fields
</form>

Le code PHP de base

if (isset($_POST['g-recaptcha-response'])) {
    $captcha = $_POST['g-recaptcha-response'];
} else {
    $captcha = false;
}

if (!$captcha) {
    //Do something with error
} else {
    $secret   = 'Your secret key here';
    $response = file_get_contents(
        "https://www.google.com/recaptcha/api/siteverify?secret=" . $secret . "&response=" . $captcha . "&remoteip=" . $_SERVER['REMOTE_ADDR']
    );
    // use json_decode to extract json response
    $response = json_decode($response);

    if ($response->success === false) {
        //Do something with error
    }
}

//... The Captcha is valid you can continue with the rest of your code
//... Add code to filter access using $response . score
if ($response->success==true && $response->score <= 0.5) {
    //Do something to denied access
}

Vous devez filtrer l'accès en utilisant la valeur de $response.score. Elle peut prendre des valeurs de 0,0 à 1,0, où 1,0 signifie la meilleure interaction de l'utilisateur avec votre site et 0,0 la pire interaction (comme un bot). Vous pouvez voir quelques exemples d'utilisation dans Documentation ReCaptcha .

3 votes

Le code que vous avez posté ne vérifie pas la valeur de l'option score si je comprends bien le docs correctement, success indique seulement si la demande affichée était valide ; les informations réelles sur l'interaction (c'est-à-dire légitime ou non) sont contenues dans la balise score champ.

0 votes

Vous avez raison, c'est juste un code de base pour que ReCaptcha fonctionne. Mais prévenir que le filtre se fait par le "score" est nécessaire, merci.

0 votes

Pour éviter le timeout-or-duplicate je suggère d'utiliser setInterval pour rafraîchir le jeton ( exemple )

14voto

Gatsby Points 445

J'ai pensé qu'une démonstration d'exemple de reCaptcha v3 en PHP, utilisant un formulaire Bootstrap 4, pourrait être utile à certains. Référencez les dépendances indiquées, insérez votre adresse email et vos clés (créez vos propres clés ici :  https://www.google.com/recaptcha/intro/v3.html ), et le formulaire est prêt à être testé et utilisé. J'ai fait des commentaires sur le code pour mieux clarifier la logique et j'ai également inclus des lignes log et print_r de la console commentées pour permettre de visualiser rapidement le jeton de validation et les données générées par Google. La fonction jQuery incluse est facultative, bien qu'elle crée une bien meilleure expérience d'invite pour l'utilisateur dans cette démo.

Fichier PHP (mail.php) :

<?php

if ($_SERVER["REQUEST_METHOD"] == "POST") {

    # BEGIN Setting reCaptcha v3 validation data
    $url = "https://www.google.com/recaptcha/api/siteverify";
    $data = [
        'secret' => "your-secret-key-here",
        'response' => $_POST['token'],
        'remoteip' => $_SERVER['REMOTE_ADDR']
    ];

    $options = array(
        'http' => array(
          'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
          'method'  => 'POST',
          'content' => http_build_query($data)
        )
      );

    # Creates and returns stream context with options supplied in options preset 
    $context  = stream_context_create($options);
    # file_get_contents() is the preferred way to read the contents of a file into a string
    $response = file_get_contents($url, false, $context);
    # Takes a JSON encoded string and converts it into a PHP variable
    $res = json_decode($response, true);
    # END setting reCaptcha v3 validation data

    // print_r($response); 

    # Post form OR output alert and bypass post if false. NOTE: score conditional is optional, since the successful score default is set at >= 0.5 by Google. Some developers want to be able to control score result conditions, so I included that in this example.
    if ($res['success'] == true && $res['score'] >= 0.5) {

        # Recipient email
        $mail_to = "youremail@domain.com";

        # Sender form data
        $subject = trim($_POST["subject"]);
        $name = str_replace(array("\r","\n"),array(" "," ") , strip_tags(trim($_POST["name"])));
        $email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
        $phone = trim($_POST["phone"]);
        $message = trim($_POST["message"]);

        if (empty($name) OR !filter_var($email, FILTER_VALIDATE_EMAIL) OR empty($phone) OR empty($subject) OR empty($message)) {
            # Set a 400 (bad request) response code and exit
            http_response_code(400);
            echo '<p class="alert-warning">Please complete the form and try again.</p>';
            exit;
        }

        # Mail content
        $content = "Name: $name\n";
        $content .= "Email: $email\n\n";
        $content .= "Phone: $phone\n";
        $content .= "Message:\n$message\n";

        # Email headers
        $headers = "From: $name <$email>";

        # Send the email
        $success = mail($mail_to, $subject, $content, $headers);

        if ($success) {
            # Set a 200 (okay) response code
            http_response_code(200);
            echo '<p class="alert alert-success">Thank You! Your message has been successfully sent.</p>';
        } else {
            # Set a 500 (internal server error) response code
            http_response_code(500);
            echo '<p class="alert alert-warning">Something went wrong, your message could not be sent.</p>';
        }   

    } else {

        echo '<div class="alert alert-danger">
                Error! The security token has expired or you are a bot.
             </div>';
    }  

} else {
    # Not a POST request, set a 403 (forbidden) response code
    http_response_code(403);
    echo '<p class="alert-warning">There was a problem with your submission, please try again.</p>';
} ?>

HTML - placez la dépendance CSS de Bootstrap et la validation côté client de reCaptcha (n'oubliez pas de coller votre propre clé de site) entre les balises d'en-tête :

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://www.google.com/recaptcha/api.js?render=your-site-key-here"></script>

HTML - à placer entre les balises du corps :

 <!-- contact form demo container -->
<section style="margin: 50px 20px;">
    <div style="max-width: 768px; margin: auto;">

        <!-- contact form -->
        <div class="card">
            <h2 class="card-header">Contact Form</h2>
            <div class="card-body">
                <form class="contact_form" method="post" action="mail.php">

                    <!-- form fields -->
                    <div class="row">
                        <div class="col-md-6 form-group">
                            <input name="name" type="text" class="form-control" placeholder="Name" required>
                        </div>
                        <div class="col-md-6 form-group">
                            <input name="email" type="email" class="form-control" placeholder="Email" required>
                        </div>
                        <div class="col-md-6 form-group">
                            <input name="phone" type="text" class="form-control" placeholder="Phone" required>
                        </div>
                        <div class="col-md-6 form-group">
                            <input name="subject" type="text" class="form-control" placeholder="Subject" required>
                        </div>
                        <div class="col-12 form-group">
                            <textarea name="message" class="form-control" rows="5" placeholder="Message" required></textarea>
                        </div>

                        <!-- form message prompt -->
                        <div class="row">
                            <div class="col-12">
                                <div class="contact_msg" style="display: none">
                                    <p>Your message was sent.</p>
                                </div>
                            </div>
                        </div>

                        <div class="col-12">
                            <input type="submit" value="Submit Form" class="btn btn-success" name="post">
                        </div>

                        <!-- hidden reCaptcha token input -->
                        <input type="hidden" id="token" name="token">
                    </div>

                </form>
            </div>
        </div>

    </div>
</section>
<script>
    grecaptcha.ready(function() {
        grecaptcha.execute('your-site-key-here', {action: 'homepage'}).then(function(token) {
           // console.log(token);
           document.getElementById("token").value = token;
        });
    });
</script>

<!-- References for the opitional jQuery function to enhance end-user prompts -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="form.js"></script>

Fonction jQuery facultative pour une meilleure ergonomie (form.js) :

(function ($) {
'use strict';

var form = $('.contact_form'),
    message = $('.contact_msg'),
    form_data;

// Success function
function done_func(response) {
    message.fadeIn()
    message.html(response);
    setTimeout(function () {
        message.fadeOut();
    }, 10000);
    form.find('input:not([type="submit"]), textarea').val('');
}

// fail function
function fail_func(data) {
    message.fadeIn()
    message.html(data.responseText);
    setTimeout(function () {
        message.fadeOut();
    }, 10000);
}

form.submit(function (e) {
    e.preventDefault();
    form_data = $(this).serialize();
    $.ajax({
        type: 'POST',
        url: form.attr('action'),
        data: form_data
    })
    .done(done_func)
    .fail(fail_func);
}); })(jQuery);

3 votes

Très complet ; j'ai réussi à faire fonctionner celui-ci rapidement après avoir abandonné les autres réponses (plus élevées). Merci !

0 votes

Note : " reCAPTCHA tokens expire after two minutes. If you're protecting an action with reCAPTCHA, make sure to call execute when the user takes the action rather than on page load. "( src ) C'est particulièrement important dans un formulaire de commentaire - cela m'est arrivé en tant qu'utilisateur sur des sites en direct, après avoir tapé des commentaires détaillés (longs) et en colère, et ensuite le formulaire du site ne me permet pas de les soumettre. Cela peut être très frustrant !

1 votes

@ashleedawg modifié pour inclure le rafraîchissement du jeton toutes les 60 secondes.

6voto

Shaikh Shahid Points 831

Je suppose que vous avez mis en place la clé et le secret du site. Suivez cette étape.

Dans votre fichier HTML, ajoutez le script.

 <script src="https://www.google.com/recaptcha/api.js?render=put your site key here"></script>

Utilisez également jQuery pour faciliter la gestion des événements.

Voici le formulaire simple.

 <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>

Vous devez initialiser le recaptcha de Google et écouter l'événement ready. Voici comment faire.

     <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>

Voici l'exemple de fichier PHP. Vous pouvez utiliser Servlet ou Node ou tout autre langage backend à la place.

<?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'));
        }
?>

Voici le lien du tutoriel : https://codeforgeek.com/2019/02/google-recaptcha-v3-tutorial/

J'espère que cela vous aidera.

6 votes

C'est faux et ne prend pas en compte le score qui est nécessaire dans la v3. Ne suivez pas ce guide, lisez les commentaires sur la page liée.

0 votes

Après n'avoir eu aucun succès avec plusieurs réponses (dont celle-ci), j'ai eu plus de chance avec cette réponse .

3voto

Furqan Freed Points 73

Nous utilisons recaptcha-V3 uniquement pour voir la qualité du trafic du site, et nous l'avons utilisé comme non bloquant. Étant donné que recaptcha-V3 n'a pas besoin d'être affiché sur le site et peut être utilisé comme caché, mais vous devez afficher les liens recaptcha privacy etc.

Balise script dans l'en-tête

<script src="https://www.google.com/recaptcha/api.js?onload=ReCaptchaCallbackV3&render='SITE KEY' async defer></script>

Note : "async defer" assurez-vous qu'il n'est pas bloquant, ce qui est notre exigence spécifique.

Code JS :

<script>
    ReCaptchaCallbackV3 = function() {
        grecaptcha.ready(function() {
            grecaptcha.execute("SITE KEY").then(function(token) {
                $.ajax({
                    type: "POST",
                    url: `https://api.${window.appInfo.siteDomain}/v1/recaptcha/score`,
                    data: {
                        "token" : token,
                    },
                    success: function(data) {
                        if(data.response.success) {
                            window.recaptchaScore = data.response.score;
                            console.log('user score ' + data.response.score)
                        }
                    },
                    error: function() {
                        console.log('error while getting google recaptcha score!')
                    }
                });

            });
        });
    };
</script> 

Code HTML/Css :

there is no html code since our requirement is just to get score and don't want to show recaptcha badge.

Backend - Laravel Code :

Route:

Route::post('/recaptcha/score', 'Api\\ReCaptcha\\RecaptchaScore@index');

Class:

class RecaptchaScore extends Controller
{
    public function index(Request $request)
    {
        $score = null;

        $response = (new Client())->request('post', 'https://www.google.com/recaptcha/api/siteverify', [
            'form_params' => [
                'response' => $request->get('token'),
                'secret' => 'SECRET HERE',
            ],
        ]);

        $score = json_decode($response->getBody()->getContents(), true);

        if (!$score['success']) {
            Log::warning('Google ReCaptcha Score', [
                'class' => __CLASS__,
                'message' => json_encode($score['error-codes']),
            ]);
        }

        return [
            'response' => $score,
        ];
    }
} 

nous récupérons le score et le sauvegardons dans une variable que nous utilisons plus tard lorsque nous soumettons le formulaire.

Référence : https://developers.google.com/recaptcha/docs/v3 https://developers.google.com/recaptcha/

0 votes

Après n'avoir eu aucun succès avec plusieurs réponses (dont celle-ci), j'ai eu plus de chance avec cette réponse .

0 votes

@ashleedawg désolé si cela n'a pas fonctionné pour vous ! je viens juste de tester à nouveau et il semble que tout soit bon ! votre référence est une simple implémentation php si vous utilisez cette colonne qui, je l'ai mentionné, est écrite pour #Laravel mais cela devrait également fonctionner si vous utilisez simplement la classe RecaptchaScore.

0voto

burkul Points 35

Si vous venez d'implémenter recaptcha sur votre site, je vous suggère d'ajouter api.js et de laisser google collecter les données comportementales de vos utilisateurs pendant 1-2 jours. C'est beaucoup plus sûr de cette façon, surtout avant de commencer à utiliser le score.

0 votes

Bienvenue chez SO ! Des informations ou des liens supplémentaires seraient utiles. (Regardez Comment répondre .)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X