web-dev-qa-db-fra.com

ReCaptcha 2.0 avec AJAX

J'ai réussi à faire fonctionner ReCaptcha 2.0 sur mon site web. Cependant, cela ne fonctionne que lorsque je n'utilise pas AJAX et que je laisse le formulaire se soumettre "naturellement".

Je veux soumettre le formulaire avec le captcha et alerter l'utilisateur avec une note de réussite sans actualiser la page.

J'ai essayé le code suivant, mais il semble que le serveur ne reçoive pas la réponse de l'utilisateur:

HTML:

<form class="form" action="javascript:void(0)" novalidate>
    <!-- all the inputs... -->

    <!-- captcha -->
    <div class="input-group">
        <div class="g-recaptcha" data-sitekey="6LdOPgYTAAAAAE3ltWQGar80KUavaR-JblgPZjDI"></div>
    </div>

    <div class="errors" id="errors" style="display: none"></div>

    <div class="input-group">
        <input type="button" value="Send" class="btn-default right" id="submit">
        <div class="clear"></div>
    </div>
</form>

JS:

$('#submit').click(function(e) {
    console.log('clicked submit'); // --> works

    var $errors = $('#errors'),
        $status = $('#status'),

        name = $('#name').val().replace(/<|>/g, ""), // prevent xss
        email = $('#email').val().replace(/<|>/g, ""),
        msg = $('#message').val().replace(/<|>/g, "");

    if (name == '' || email == '' || msg == '') {
        valid = false;
        errors = "All fields are required.";
    }

    // pretty sure the problem is here
    console.log('captcha response: ' + grecaptcha.getResponse()); // --> captcha response: 

    if (!errors) {
        // hide the errors
        $errors.slideUp();
        // ajax to the php file to send the mail
        $.ajax({
            type: "POST",
            url: "http://orenurbach.com/assets/sendmail.php",
            data: "email=" + email + "&name=" + name + "&msg=" + msg + "&g-recaptcha-response=" + grecaptcha.getResponse()
        }).done(function(status) {
            if (status == "ok") {
                // slide down the "ok" message to the user
                $status.text('Thanks! Your message has been sent, and I will contact you soon.');
                $status.slideDown();
                // clear the form fields
                $('#name').val('');
                $('#email').val('');
                $('#message').val('');
            }
        });
    } else {
        $errors.text(errors);
        $errors.slideDown();
    }
});

PHP:

<?php
    // assemble the message from the POST fields

    // getting the captcha
    $captcha = '';
    if (isset($_POST['g-recaptcha-response']))
        $captcha = $_POST['g-recaptcha-response'];
    echo 'captcha: '.$captcha;

    if (!$captcha)
        echo 'The captcha has not been checked.';
    // handling the captcha and checking if it's ok
    $secret = 'MY_SECRET';
    $response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']), true);

    var_dump($response);

    // if the captcha is cleared with google, send the mail and echo ok.
    if ($response['success'] != false) {
        // send the actual mail
        @mail($email_to, $subject, $finalMsg);

        // the echo goes back to the ajax, so the user can know if everything is ok
        echo 'ok';
    } else {
        echo 'not ok';
    }
?>

Le résultat dans la PHP page:

captcha: The captcha has not been checked.array(2) { ["success"]=> bool(false) ["error-codes"]=> array(1) { [0]=> string(22) "missing-input-response" } } not ok

Conclusion comment puis-je obtenir manuellement la réponse en entrée sans que celle-ci se retrouve automatiquement avec le reste des données POST?

50
Gofilord

Ok, c'était plutôt idiot.

J'ai mal fait plusieurs choses:

  • Dans le fichier PHP, toutes les chaînes avaient des guillemets simples, ce qui posait des problèmes.
  • Tout au long des tests, j’ai ajouté plusieurs impressions de choses dans le fichier PHP, ainsi la if (status == "ok")] ne fonctionnait jamais. J’ai reçu les courriels, mais je n’ai reçu aucune confirmation fait et maintenant je vois pourquoi.
  • Lorsque je voulais vérifier ce que le fichier PHP omettait), je suis simplement allé à l'adresse indiquée dans l'URL et j'ai toujours une erreur. Même lorsque les e-mails ont été envoyés. Je comprends maintenant que ce n'est pas le cas la bonne façon de vérifier les journaux.

Merci à @Samurai qui m'a aidé à comprendre les choses.


Final PHP code:

<?php
    // assemble the message from the POST fields

    // getting the captcha
    $captcha = "";
    if (isset($_POST["g-recaptcha-response"]))
        $captcha = $_POST["g-recaptcha-response"];

    if (!$captcha)
        echo "not ok";
    // handling the captcha and checking if it's ok
    $secret = "MY_SECRET";
    $response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER["REMOTE_ADDR"]), true);

    // if the captcha is cleared with google, send the mail and echo ok.
    if ($response["success"] != false) {
        // send the actual mail
        @mail($email_to, $subject, $finalMsg);

        // the echo goes back to the ajax, so the user can know if everything is ok
        echo "ok";
    } else {
        echo "not ok";
    }
?>
26
Gofilord