Recaptcha ошибка timeout or duplicate

This page explains how to verify a user’s response to a reCAPTCHA challenge from your application’s
backend.

For web users, you can get the user’s response token in one of three ways:

  • g-recaptcha-response POST parameter when the user submits the form on your site
  • grecaptcha.getResponse(opt_widget_id) after the user completes
    the reCAPTCHA challenge
  • As a string argument to your callback function
    if data-callback is specified in either the g-recaptcha tag attribute or
    the callback parameter in the grecaptcha.render method

For Android library users, you can call the
SafetyNetApi.RecaptchaTokenResult.getTokenResult()
method to get response token if the status returns successful.

Token Restrictions

Each reCAPTCHA user response token is valid for two minutes, and can only be verified once to
prevent replay attacks. If you need a new token, you can re-run the reCAPTCHA verification.

After you get the response token, you need to verify it within two minutes with reCAPTCHA using the
following API to ensure the token is valid.

API Request

URL: https://www.google.com/recaptcha/api/siteverify
METHOD: POST

POST Parameter Description
secret Required. The shared key between your site and reCAPTCHA.
response Required. The user response token provided by the reCAPTCHA client-side integration on your site.
remoteip Optional. The user’s IP address.

API Response

The response is a JSON object:

{
  "success": true|false,
  "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
}

For reCAPTCHA Android:

{
  "success": true|false,
  "challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
  "apk_package_name": string, // the package name of the app where the reCAPTCHA was solved
  "error-codes": [...]        // optional
}

Error code reference

Error code Description
missing-input-secret The secret parameter is missing.
invalid-input-secret The secret parameter is invalid or malformed.
missing-input-response The response parameter is missing.
invalid-input-response The response parameter is invalid or malformed.
bad-request The request is invalid or malformed.
timeout-or-duplicate The response is no longer valid: either is too old or has been used previously.

I got a contact form on my website on Laravel and I’d like to place a ReCaptcha v3 but for now the result I got from the verification is the error «timeout-or-duplicate».

Can you help me from A to Z ? I don’t know where to go…

My head :

<script src="https://www.google.com/recaptcha/api.js?render=My_Site_Key"></script>
  <script>
    grecaptcha.ready(function () {
      grecaptcha.execute('My_Site_Key', { action: 'contact' }).then(function (token) {
        var recaptchaResponse = document.getElementById('recaptchaResponse');
          recaptchaResponse.value = token;
      });
    });
  </script>

The contact form :

<form action="{{ route('contact.post') }}" id="contact-form" method="post" name="contactForm">
   <input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
   <input type="hidden" name="recaptcha_response" id="recaptchaResponse">
   <fieldset>
     <div class="col-sm-12">
       <input id="name" name="name" placeholder="Nom*" type="text">
     </div>
     <div class="col-sm-12">
       <input id="email" name="email" placeholder="Email*" type="text">
     </div>
     <div class="col-sm-12">
       <input id="object" name="object" placeholder="Objet*" type="text" autocomplete="off">
     </div>
     <div class="col-xs-12">
       <textarea cols="5" id="message" name="message" placeholder="Votre message...*"></textarea>
     </div>
     <div class="col-xs-12">
       <button class="submit active" id="contact-submit">ENVOYER</button>
     </div>
     <div class="error col-xs-12">
       <h3></h3>
     </div>
     <div class="success col-xs-12">
       <h3>Merci ! Votre message a été envoyé !</h3>
     </div>
   </fieldset>
</form>

Route:

Route::post('/contact', array('as' => 'contact.post', 'uses' => 'ContactController@send'));

The Contact Controller :

<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppHttpRequests;
use IlluminateSupportFacadesInput;
use IlluminateSupportFacadesMail;

class ContactController extends Controller
{
    public function send() {
      $info = array(
          'name' => Input::get('name'),
          'email' => Input::get('email'),
          'object' => Input::get('object'),
          'message' => Input::get('message')
      );
      if($info['name'] == "" || $info['email'] == "" || $info['object'] == "" || $info['message'] == "") {
          return json_encode(['response' => 'Tous les champs doivent être remplis !']);
      }
      if(!filter_var($info['email'], FILTER_VALIDATE_EMAIL)) {
          return json_encode(['response' => 'Vous devez rentrer une adresse e-mail valide !']);
      }
      $ip = Request()->ip();

      // Build POST request:
      $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
      $recaptcha_secret = 'My_Secret_Key';
      $recaptcha_response = $_POST['recaptcha_response'];
      // Make and decode POST request:
      $recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
      $recaptcha = json_decode($recaptcha);
      // Take action based on the score returned:
      if ($recaptcha->score < 0.5) {
          return json_encode(['response' => 'Vous êtes considéré comme Bot/Spammer !', 'score' => $recaptcha->score]);
      }

      Mail::send(['email.html.contact', 'email.text.contact'], ['info' => $info, 'ip' => $ip], function($message) use ($info) {
          $message->to('contact@bryangossuin.be')->subject('Bryan Gossuin | Formulaire de contact');
          $message->replyTo($info['email'], $info['name']);
      });
      return json_encode(['response' => 'success','']);
  }
}

Finaly the javascript

      $('#contact-form').on('submit', function(e) {
          e.preventDefault();
          swal({
              title: "Souhaitez-vous vraiment envoyer ce mail ?",
              icon: "warning",
              buttons: {
                cancel: {
                  text: "Annuler",
                  value: false,
                  visible: true,
                  closeModal: true,
                },
                confirm: "Envoyer",
              }
            })
            .then((value) => {
              if (value) {
                  $.ajax({
                          method: "POST",
                          url: "contact",
                          cache: false,
                          data: $(this).serialize(),
                          dataType: 'json',
                          success: function(json) {
                              console.log(json.score);
                              if (json.response == 'success') {
                                  $('#contact-form').trigger("reset");
                                  swal("E-mail envoyé", "Merci de votre demande !", "success");
                              } else {
                                  swal("Erreur !", json.response, "error");
                              }
                          }
                      }
                  )
               }
            });
      });

The output I got from google is

{
  "success": false,
  "error-codes": [
    "timeout-or-duplicate"
  ]
}

and I expect it to be

{
  "success": true,
  "score" : x,
  "error-codes": '',
}

I guess the problem is because the « method post » is used two times because when I Check directly
On the API Google to verify the user token it show le thé code but right after I refresh the page it show me « timeout or duplicate » but I dont know how to fix this

    <script>
        grecaptcha.ready(function () {
            grecaptcha.execute('GOOGLE CLIENT KEY', {action: 'contact'}).then(function(token) {
                $('#email_form').prepend('<input id="recaptcha_token" type="hidden" name="token" value="' + token + '">');
                console.log("recaptcha_token set on email_form >> token = " + token);
            });
            setInterval(function () {
                grecaptcha.execute('GOOGLE CLIENT KEY', { action: 'contact' }).then(function (token) {
                    if ($("#recaptcha_token").length) {
                        console.log("set new token to existing input >> token = " + token);
                        $("#recaptcha_token").val(token);
                    } else {
                        console.error("recaptcha_token does not exist on email_form");
                    }
                });
            }, 60000);
        });      
    </script>

I set the interval to one minute because I have no idea how long it takes for the timeout-or-duplicate error to occur.

Answer by Natasha Pena

Token has been used previously. To confirm that, log the token value before is used (error log, local file, whatever),Validity time of the token expired (After you get the response token, you need to verify it within two minutes),Thus, if you spend more then 2 minutes on the contact-form, you get the timout error,. Thats why its recommended in the docs to only call execute if the user actually submits your form / takes action. In vanilla JS it would look like this:,I guess the problem is because the « method post » is used two times because when I Check directly
On the API Google to verify the user token it show le thé code but right after I refresh the page it show me « timeout or duplicate » but I dont know how to fix this

My resolution for 1, set an interval that calls the set token function, so it is refreshed every 2 minutes.

$(document).ready(function() {

            SetCaptchaToken();
            setInterval(function () { SetCaptchaToken(); }, 2 * 60 * 1000);

    });

Answer by Declan Barrera

I set the interval to one minute because I have no idea how long it takes for the timeout-or-duplicate error to occur.,When using V3, the docs suggest that you can perform a grecaptcha.execute on page load.,I call this method just before send the form to the server, but ocassionally still have the «timeout-or-duplicate» error.«,I am finding though, that sporadically, some site verify responses are returning timeout-or-duplicate when I do a server-side site verification.

    <script>
        grecaptcha.ready(function () {
            grecaptcha.execute('GOOGLE CLIENT KEY', {action: 'contact'}).then(function(token) {
                $('#email_form').prepend('<input id="recaptcha_token" type="hidden" name="token" value="' + token + '">');
                console.log("recaptcha_token set on email_form >> token = " + token);
            });
            setInterval(function () {
                grecaptcha.execute('GOOGLE CLIENT KEY', { action: 'contact' }).then(function (token) {
                    if ($("#recaptcha_token").length) {
                        console.log("set new token to existing input >> token = " + token);
                        $("#recaptcha_token").val(token);
                    } else {
                        console.error("recaptcha_token does not exist on email_form");
                    }
                });
            }, 60000);
        });      
    </script>

Answer by Dante Michael

/Recibí el error «timeout-or-duplicate» usando ReCaptcha v3,Recibí un formulario de contacto en mi sitio web en Laravel y me gustaría colocar un ReCaptcha v3, pero por ahora el resultado que obtuve de la verificación es el error «timeout-or-duplicate».,Recaptcha no se verifica con file_get_contents,Como se indica en documentación este error es causado por:

Mi cabeza :

<script src="https://www.google.com/recaptcha/api.js?render=My_Site_Key"></script>
  <script>
    grecaptcha.ready(function () {
      grecaptcha.execute('My_Site_Key', { action: 'contact' }).then(function (token) {
        var recaptchaResponse = document.getElementById('recaptchaResponse');
          recaptchaResponse.value = token;
      });
    });
  </script>

El formulario de contacto:

<form action="{{ route('contact.post') }}" id="contact-form" method="post" name="contactForm">
   <input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
   <input type="hidden" name="recaptcha_response" id="recaptchaResponse">
   <fieldset>
     <div class="col-sm-12">
       <input id="name" name="name" placeholder="Nom*" type="text">
     </div>
     <div class="col-sm-12">
       <input id="email" name="email" placeholder="Email*" type="text">
     </div>
     <div class="col-sm-12">
       <input id="object" name="object" placeholder="Objet*" type="text" autocomplete="off">
     </div>
     <div class="col-xs-12">
       <textarea cols="5" id="message" name="message" placeholder="Votre message...*"></textarea>
     </div>
     <div class="col-xs-12">
       <button class="submit active" id="contact-submit">ENVOYER</button>
     </div>
     <div class="error col-xs-12">
       <h3></h3>
     </div>
     <div class="success col-xs-12">
       <h3>Merci ! Votre message a été envoyé !</h3>
     </div>
   </fieldset>
</form>

Ruta:

Route::post('/contact', array('as' => 'contact.post', 'uses' => '[email protected]'));

El controlador de contacto:

<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppHttpRequests;
use IlluminateSupportFacadesInput;
use IlluminateSupportFacadesMail;

class ContactController extends Controller
{
    public function send() {
      $info = array(
          'name' => Input::get('name'),
          'email' => Input::get('email'),
          'object' => Input::get('object'),
          'message' => Input::get('message')
      );
      if($info['name'] == "" || $info['email'] == "" || $info['object'] == "" || $info['message'] == "") {
          return json_encode(['response' => 'Tous les champs doivent être remplis !']);
      }
      if(!filter_var($info['email'], FILTER_VALIDATE_EMAIL)) {
          return json_encode(['response' => 'Vous devez rentrer une adresse e-mail valide !']);
      }
      $ip = Request()->ip();

      // Build POST request:
      $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
      $recaptcha_secret = 'My_Secret_Key';
      $recaptcha_response = $_POST['recaptcha_response'];
      // Make and decode POST request:
      $recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
      $recaptcha = json_decode($recaptcha);
      // Take action based on the score returned:
      if ($recaptcha->score < 0.5) {
          return json_encode(['response' => 'Vous êtes considéré comme Bot/Spammer !', 'score' => $recaptcha->score]);
      }

      Mail::send(['email.html.contact', 'email.text.contact'], ['info' => $info, 'ip' => $ip], function($message) use ($info) {
          $message->to('[email protected]')->subject('Bryan Gossuin | Formulaire de contact');
          $message->replyTo($info['email'], $info['name']);
      });
      return json_encode(['response' => 'success','']);
  }
}

Finalmente el javascript

      $('#contact-form').on('submit', function(e) {
          e.preventDefault();
          swal({
              title: "Souhaitez-vous vraiment envoyer ce mail ?",
              icon: "warning",
              buttons: {
                cancel: {
                  text: "Annuler",
                  value: false,
                  visible: true,
                  closeModal: true,
                },
                confirm: "Envoyer",
              }
            })
            .then((value) => {
              if (value) {
                  $.ajax({
                          method: "POST",
                          url: "contact",
                          cache: false,
                          data: $(this).serialize(),
                          dataType: 'json',
                          success: function(json) {
                              console.log(json.score);
                              if (json.response == 'success') {
                                  $('#contact-form').trigger("reset");
                                  swal("E-mail envoyé", "Merci de votre demande !", "success");
                              } else {
                                  swal("Erreur !", json.response, "error");
                              }
                          }
                      }
                  )
               }
            });
      });

La salida que obtuve de google es

{
  "success": false,
  "error-codes": [
    "timeout-or-duplicate"
  ]
}

y espero que sea

{
  "success": true,
  "score" : x,
  "error-codes": '',
}

Answer by Rayna Schwartz

3. Marketo would call the validation web service using a webhook after a form was submitted and blacklist any leads for which the response returned success = false. The timestamp would be used for a Change Data Value trigger.,2. Create a simple validation web service that would take an email address and a signature and return a JSON object like this,1. Instead of sending a reCaptcha fingerprint with the form submission, submit a custom signature that would be calculated in the browser based on email address, e.g. sha256 of email address.,Not bulletproof against a determined attacker — they could fake the email signature if they went through the trouble of looking at the form submission code

2. Create a simple validation web service that would take an email address and a signature and return a JSON object like this

{  "success": true|false,      // whether the signature matches the email address  "response_ts": timestamp    // timestamp of the response (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)}

Answer by Esmeralda Harrington

Наконец то javascript

Моя голова :

<script src="https://www.google.com/recaptcha/api.js?render=My_Site_Key"></script>
  <script>
    grecaptcha.ready(function () {
      grecaptcha.execute('My_Site_Key', { action: 'contact' }).then(function (token) {
        var recaptchaResponse = document.getElementById('recaptchaResponse');
          recaptchaResponse.value = token;
      });
    });
  </script>

Контактная форма :

<form action="{{ route('contact.post') }}" id="contact-form" method="post" name="contactForm">
   <input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
   <input type="hidden" name="recaptcha_response" id="recaptchaResponse">
   <fieldset>
     <div class="col-sm-12">
       <input id="name" name="name" placeholder="Nom*" type="text">
     </div>
     <div class="col-sm-12">
       <input id="email" name="email" placeholder="Email*" type="text">
     </div>
     <div class="col-sm-12">
       <input id="object" name="object" placeholder="Objet*" type="text" autocomplete="off">
     </div>
     <div class="col-xs-12">
       <textarea cols="5" id="message" name="message" placeholder="Votre message...*"></textarea>
     </div>
     <div class="col-xs-12">
       <button class="submit active" id="contact-submit">ENVOYER</button>
     </div>
     <div class="error col-xs-12">
       <h3></h3>
     </div>
     <div class="success col-xs-12">
       <h3>Merci ! Votre message a été envoyé !</h3>
     </div>
   </fieldset>
</form>

Маршрут:

Route::post('/contact', array('as' => 'contact.post', 'uses' => '[email protected]'));

Контактный Контроллер :

<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppHttpRequests;
use IlluminateSupportFacadesInput;
use IlluminateSupportFacadesMail;

class ContactController extends Controller
{
    public function send() {
      $info = array(
          'name' => Input::get('name'),
          'email' => Input::get('email'),
          'object' => Input::get('object'),
          'message' => Input::get('message')
      );
      if($info['name'] == "" || $info['email'] == "" || $info['object'] == "" || $info['message'] == "") {
          return json_encode(['response' => 'Tous les champs doivent être remplis !']);
      }
      if(!filter_var($info['email'], FILTER_VALIDATE_EMAIL)) {
          return json_encode(['response' => 'Vous devez rentrer une adresse e-mail valide !']);
      }
      $ip = Request()->ip();

      // Build POST request:
      $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
      $recaptcha_secret = 'My_Secret_Key';
      $recaptcha_response = $_POST['recaptcha_response'];
      // Make and decode POST request:
      $recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
      $recaptcha = json_decode($recaptcha);
      // Take action based on the score returned:
      if ($recaptcha->score < 0.5) {
          return json_encode(['response' => 'Vous êtes considéré comme Bot/Spammer !', 'score' => $recaptcha->score]);
      }

      Mail::send(['email.html.contact', 'email.text.contact'], ['info' => $info, 'ip' => $ip], function($message) use ($info) {
          $message->to('[email protected]')->subject('Bryan Gossuin | Formulaire de contact');
          $message->replyTo($info['email'], $info['name']);
      });
      return json_encode(['response' => 'success','']);
  }
}

Наконец то javascript

      $('#contact-form').on('submit', function(e) {
          e.preventDefault();
          swal({
              title: "Souhaitez-vous vraiment envoyer ce mail ?",
              icon: "warning",
              buttons: {
                cancel: {
                  text: "Annuler",
                  value: false,
                  visible: true,
                  closeModal: true,
                },
                confirm: "Envoyer",
              }
            })
            .then((value) => {
              if (value) {
                  $.ajax({
                          method: "POST",
                          url: "contact",
                          cache: false,
                          data: $(this).serialize(),
                          dataType: 'json',
                          success: function(json) {
                              console.log(json.score);
                              if (json.response == 'success') {
                                  $('#contact-form').trigger("reset");
                                  swal("E-mail envoyé", "Merci de votre demande !", "success");
                              } else {
                                  swal("Erreur !", json.response, "error");
                              }
                          }
                      }
                  )
               }
            });
      });

Вывод, который я получил от google, таков

{
  "success": false,
  "error-codes": [
    "timeout-or-duplicate"
  ]
}

и я ожидаю, что так оно и будет

{
  "success": true,
  "score" : x,
  "error-codes": '',
}

I’m trying to implement Google reCaptcha v2 on a wizard form. If I complete the captcha and submit the form without having filled out the other fields, it returns result:

{'success': True, 'challenge_ts': '2018-10-30T21:47:25Z', 'hostname': '127.0.0.1'}.

But if I fill out all the required fields so that the form is valid it returns result:

{'success': True, 'challenge_ts': '2018-10-30T21:47:25Z', 'hostname': '127.0.0.1'}.
{'success': False, 'error-codes': ['timeout-or-duplicate']}
[30/Oct/2018 21:47:44] "POST /register/ HTTP/1.1" 200 3912

rendering the form invalid, and throwing an invalid captcha error. I’m guessing that the problem is that the captcha is being validated twice. My verify captcha logic is in the form clean method, so maybe that is the problem:

def clean(self):
    cleaned_data = super(Form, self).clean()
    recaptcha_response = self.request.POST.get('g-recaptcha-response')
    url = 'https://www.google.com/recaptcha/api/siteverify'
    values = {
            'secret': settings.RECAPTCHA_SECRET_KEY,
            'response': recaptcha_response
        }
    data = urllib.parse.urlencode(values).encode()
    req =  urllib.request.Request(url, data=data)
    response = urllib.request.urlopen(req)
    result = json.loads(response.read().decode())
    print (result)
    if result['success']:
        return cleaned_data
    else:
        raise forms.ValidationError('Error.')

I’m wondering if it’s conflicting with my done method in the view:

def done(self, form_list, **kwargs):
    data = {k: v for form in form_list for k, v in form.cleaned_data.items()}

Any ideas on how to fix this?

Понравилась статья? Поделить с друзьями:
  • Rdr 2 ошибка fff unknown error
  • Recaptcha коды ошибок
  • Rdr 2 ошибка err gfx d3d deferred mem
  • Recalctotals 1с ошибка
  • Rdr 2 ошибка eom dll