Как проверить ответ Google Recaptcha V3

Как интегрировать Google reCAPTCHA версии 3 на стороне клиента и на стороне сервера (php). следующий код используется для отображения recaptcha, но он не работает хорошо. Как сделать эту интеграцию.

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

Ответы

Ответ 1

Попробуй это.

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

Ответ 2

<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 

На этом этапе кода вам нужно будет отправить запрос в ReCAPTCHA для проверки токена, как описано здесь: https://www.google.com/recaptcha/api/siteverify. Ответом будет объект json с полем "успех" (true/false) и "действие" для сравнения (==) и оценки (число от 0.0 до 1.0)

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

Вы также можете указать имя действия для каждого запроса (create_post, update_post, create_comment...)

Ответ 3

Вот пример рабочего кода с демо.

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>

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

Работает нормально.

Демо: https://demo.codeforgeek.com/recaptcha-v3/

учебное пособие: https://codeforgeek.com/2019/02/google-recaptcha-v3-tutorial/

Ответ 4

Простой пример контактной формы, проверенной Google reCAPTCHA v3 с чистым JavaScript и PHP

TL;DR; пропустите код внизу.

Соответствующие документы reCAPTCHA и т.д.:

(Если Google слушает, мы любим вашу работу, и было бы замечательно, если бы несколько более сложных примеров, связанных с вышеупомянутыми страницами, пожалуйста.)

Обзор:

  1. Получить ключи от Google
  2. Загрузите recaptcha/api.js в заголовке HTML
  3. Захватите форму отправки с JavaScript и в этот момент получите токен от Google
  4. Отправьте форму с токеном на ваш сервер
  5. Отправьте запрос от вашего веб-сайта в Google, чтобы подтвердить отправку формы
  6. Интерпретируйте ответ и действуйте по мере необходимости

Важно отметить: параметр ответа "success" указывает только то, была ли проверена капча успешно, но не указывает, была ли отправка спамом или нет.

Параметр "Score" - это результат, о котором вам нужно знать. Чем выше оценка (число от 0 до 1), тем больше вероятность того, что отправка является подлинной, и вам решать, какой порог (например, 0,5) принять.

В деталях:

Добавьте следующую строку в заголовок вашего HTML-кода, чтобы загрузить код recaptcha api.js:

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

(где $reCAPTCHA_site_key - это ваш публичный "ключ сайта", который я сохранил в файле "config.php".)

Вам необходимо отправить токен (полученный от Google и уникальный для каждой отправки формы) на ваш сервер. Я думаю, что проще всего отправить его через POST вместе с остальными данными формы. С этой целью я включаю скрытое поле в форме следующим образом:

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

(Примечание. "Contact" - это contact.php, но я переписал URL с помощью .htaccess)

Теперь нам нужно перехватить отправку формы по умолчанию, чтобы сгенерировать токен. Мы могли бы сгенерировать токен при загрузке страницы, но так как токен действителен только в течение двух минут (если я правильно читаю страницу https://developers.google.com/recaptcha/docs/verify), я думаю, что лучше получить его в случае необходимости отправить его на сервер вашего сайта.

С этой целью я добавил следующее сразу после тега закрывающей формы:

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

Я поместил функцию validate(form) перед закрывающим тегом body:

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

Заметки:

  • $reCAPTCHA_site_key - ваш открытый ключ сайта
  • action: 'contactForm' идентифицирует action: 'contactForm' этой конкретной формы на панели инструментов Google reCAPTCHA, и подтверждение того, что это ожидается в бэкэнде, является рекомендуемым дополнительным шагом безопасности

В основном PHP файле при получении формы:

//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.
}

Заметки:

  • Это данные, которые будут в ответе от Google (возвращены как объект 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
   }
  • Вот возможные коды ошибок:
    • missing-input-secret: секретный параметр отсутствует.
    • invalid-input-secret: секретный параметр недействителен или имеет неправильный формат.
    • отсутствующий входной ответ: параметр ответа отсутствует.
    • invalid-input-response: параметр ответа недействителен или имеет неправильный формат.
    • плохой запрос: запрос недействителен или искажен.
    • timeout-or-duplicate: ответ больше не действителен; либо слишком стар, либо использовался ранее.

Собираем все вместе:

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.

Ответ 5

Я хотел бы дать вам полный рабочий процесс для интеграции recaptchav3 в ядро решения MVC ASP.NET.

в вашем файле appsettings.json:

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

по вашему мнению (синтаксис @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>

и в вашей форме положить это:

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

</form>

Я создаю простой метод для управления им:

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
    }

и просто я позвонил в контроллер:

 //recaptcha validation

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

обратите внимание, что я устанавливаю входные параметры из объекта "_Configuration", который представляет экземпляр объекта настройки конфигурации в Startup.cs. Вы можете передать вручную входные параметры в метод.

Наслаждайся этим

Ответ 6

Ответ Боба более прост и хорошо работает для меня, добавив ввод "action". Я просто собираюсь унифицировать коды, чтобы увидеть полный ответ, и я добавлю кое-что, чего не хватает в форме и в проверке PHP Captcha.

Основной код JS

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

Основной HTML-код

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

Основной код PHP

    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']);
        if($response.success==false)
        {
            //Do something with error
        }
    }
... The Captcha is valid you can continue with the rest of your code

Ответ 7

Ответ Боба более прост и хорошо работает для меня, добавив ввод "action". Я просто собираюсь унифицировать коды, чтобы увидеть полный ответ, и я добавлю кое-что, чего не хватает в форме и в проверке PHP Captcha.

Вы можете получить его в этом вопросе Google Recaptcha v3 пример демо