Невидимый ReCaptcha с jQuery ajax

Я пытаюсь реализовать новейшую ReCaptcha (он же "невидимый" ReCaptcha) в форме с использованием jQuery и запроса "ajax".
ReCaptcha документация:https://developers.google.com/recaptcha/docs/invisible

моя форма:

<form id="myForm" >
    <input type="email" name="email" /><br />
    <input type="password" name="password" /><br/>
    <!--<input type="submit" value="log in" />-->
    <button class="g-recaptcha" data-sitekey="6LdK..." data-callback="onSubmit">log in</button>
</form>
<div id="status"></div>

мой javascript (jQuery):

<script>

    function onSubmit(token){
        document.getElementById("myForm").submit();
    }

    $(document).ready(function(){

        $("#myForm").submit(function(event){
            event.preventDefault();
            var datas = $("#myForm").serialize();
            $.ajax({
                type: "POST",
                url: "test.php",
                data: datas,
                dataType: "json",
                    beforeSend: function(){
                        $("#status").html("logging in...");
                    },
                    success: function(response){
                        $("#status").html(response.text);
                        if(response.type=="success"){
                            window.location.replace("/myaccount");
                        }
                    },
                    error: function(){
                        $("#status").html("Failed.");
                    }
            });
        });

    });
</script>

ReCaptcha требует установить "обратный вызов данных", который я не уверен, как связать с моим уже существующим".submit(function(event)" функция.
Мой трюк" onSubmit () "не сработал, он игнорирует" ajax " и обновляет страницу.

как отправить значение " g-recaptcha-response "в моей переменной" datas", чтобы опубликовать его для тестирования.РНР?

2 ответов


Итак, вот как я решил это после копания дальше в невидимом документе reCAPTCHA и изучения немного jQuery, очевидно, так как я не был очень знаком с JS (классный материал):

мой тег головы с javascript (и немного css, чтобы удалить уродливый значок Google):

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=fr" async defer></script>

<style>
    .grecaptcha-badge{
        display:none;
    }
</style>

<script>
    var onloadCallback = function(){
        grecaptcha.render("emplacementRecaptcha",{
            "sitekey": "YOUR_RECAPTCHA_SITEKEY_HERE",
            "badge": "inline",
            "type": "image",
            "size": "invisible",
            "callback": onSubmit
        });
    };
    var onSubmit = function(token){
        var userEmail = $("#userEmail").val();
        var userPassword = $("#userPassword").val();
        var userTfaOtp = $("#userTfaOtp").val();
        $.ajax({
            type: "POST",
            url: location.href,
            data:{
                    userEmail: userEmail,
                    userPassword: userPassword,
                    userTfaOtp: userTfaOtp,
                    userJetonRecaptcha: token
                },
            dataType: "json",
                beforeSend: function(){
                    $("#statutConnexion").html("Traitement de votre requête d'authentification en cours...");
                },
                success: function(response){
                    $("#statutConnexion").html(response.Message);
                    if(response.Victoire){
                        $("#formulaireConnexion").slideUp();
                        window.location.replace("/compte");
                    }
                    else{
                        grecaptcha.reset();
                    }
                },
                error: function(){
                    $("#statutConnexion").html("La communication avec le système d'authentification n'a pas pu être établie. Veuillez réessayer.");
                    grecaptcha.reset();
                }
        });
    };
    function validate(event){
        event.preventDefault();
        $("#statutConnexion").html("Validation de votre épreuve CAPTCHA en cours...");
        grecaptcha.execute();
    }
    function onload(){
        var element = document.getElementById("boutonConnexion");
        element.onclick = validate;
    }
</script>

HTML:

<div id="formulaireConnexion">
    <input type="email" name="userEmail" id="userEmail" placeholder="Courriel" title="Courriel" required="required" /><br />
    <input type="password" name="userPassword" id="userPassword" placeholder="Mot de passe" title="Mot de passe" required="required" /><br/>
    <input type="text" name="userTfaOtp" id="userTfaOtp" placeholder="Double authentification (optionnelle)" autocomplete="off" pattern="[0-9]{6}" title="Six caractères numériques" maxlength="6" /><br />
    <div id="emplacementRecaptcha"></div>
    <button id="boutonConnexion">Connexion</button>
</div>
<div id="statutConnexion"></div>
<script>onload();</script>

Дайте мне знать, если вам нужен весь PHP, так как это выходит за рамки этого вопроса. Вероятно, вам нужно будет изменить "url: location.с href," в JS выше, так как в моем случае сценарий рендеринга HTML-формы и JS и работа с POST vars одинаковы (не велика, цель тестирования). В основном я просто проверяю POST vars, а затем, наконец, возвращаю json, как:

$jsonVictoire = true; // boolean
$jsonMessage = 'anything you want to tell your visitor'; // string

$return = 
    json_encode(
        array(
            'Victoire'=>$jsonVictoire,
            'Message'=>$jsonMessage
        )
    );
die($return);

<script defer>              
function onSubmit(token) {                      
    var f = $("#myForm");

    $.ajax({
        type: "POST",
        url: "test.php",
        data: f.serialize(),
        dataType: "json",
        beforeSend: function(){
            $("#status").html("logging in...");
        },
        success: function(response){
            $("#status").html(response.text);
            if(response.type=="success"){
                window.location.replace("/myaccount");
            } else {
                $("#status").html("Captcha failed.");
            }
        },
        error: function(){
            $("#status").html("Failed.");
        }       
    });
}
</script>

в тесте.php вам нужно проверить captcha на стороне сервера:

<?php
if(isset($_POST['g-recaptcha-response'])) {
    $result = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret=[YOUR_SECRET_KEY]&response=$_POST["g-recaptcha-response"]&remoteip=$_SERVER["REMOTE_ADDR"]'), TRUE);

    if($result['success'] == 1) {
        // Captcha ok
    } else {
        // Captcha failed
    }
}
?>