Captcha error timeout or duplicate

When using V3, the docs suggest that you can perform a grecaptcha.execute on page load. Call grecaptcha.execute on an action or when the page loads (see https://developers.google.com/recaptcha/docs...
    <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.

Содержание

  1. Verifying the user’s response
  2. Token Restrictions
  3. API Request
  4. API Response
  5. Error code reference
  6. Invisible reCAPTCHA Error: timeout-or-duplicate #30644
  7. Comments
  8. ReCAPTCHA validation failed due to: [‘timeout-or-duplicate’] #183
  9. Comments
  10. Verifying the user’s response
  11. Token Restrictions
  12. API Request
  13. API Response
  14. Error code reference
  15. Issue timeout-or-duplicate #31
  16. Comments

Verifying the user’s response

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:

For reCAPTCHA Android:

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.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Источник

Invisible reCAPTCHA Error: timeout-or-duplicate #30644

if you spend more then 2 minutes on the account registration form (might be any other form which utilizes Invisible reCAPTCHA plugin) then on submitting the form you get an Error: «timeout-or-duplicate»
If you click one more time on Submit button that form should be submitted successfully.

This happens due to the captcha token is only valid for 2 minutes after execute is called as stated in the docs: https://developers.google.com/recaptcha/docs/v3

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.

Another possible solution: set an interval that calls the set token function, so it is refreshed every 2 minutes.

The text was updated successfully, but these errors were encountered:

Variant of existing solution but extending it with the display of a countdown timer,
so the user get informed of the time limit of the actual InvisibleReCaptcha-Token.

Variant of existing solution but extending it with the display of a countdown timer,
so the user get informed of the time limit of the actual InvisibleReCaptcha-Token.

I’ve never seen a website doing that for any kind of Google Captcha.

Variant of existing solution but extending it with the display of a countdown timer,
so the user get informed of the time limit of the actual InvisibleReCaptcha-Token.

I’ve never seen a website doing that for any kind of Google Captcha.

Not for Google Captcha, but for example on online banking sites (germany), which have a max session-timout of 5-10 min,
because of security concerns, that the session is terminated on idle.

Also there is a countdown timer / visualisation in Google Authenticator to inform the user about the time left the presented code is valid.

The drawback of your second solution, to request every 2 min a new token, would may result in a runout of free API-requests,
if someone decide to DOS the registering process by spawning lots of sessions and force the plugin to request tokens for every opened registering session every two minutes.

Not for Google Captcha, but for example on online banking sites (germany), which have a max session-timout of 5-10 min,
because of security concerns, that the session is terminated on idle.

Also there is a countdown timer / visualisation in Google Authenticator to inform the user about the time left the presented code is valid.

A Captcha is not an authenticator and not a replacement for an authenticator and shall not be abused as an authenticator, so you compare apples with pears.

Where did I say that actually?

You have mentioned Google Authenticator and online banking sites as examples for a solution which might make sense for an authenticator but doesn’t make sense for a Captcha,

The problem is that the token for invRecaptcha has a lifespan of 2 minutes.

I did understand the problem, no need to explain again.

I only don’t think it should be handled in Joomla. I suppose there is no single website in the world which does such a circumstance for handling the timeout of the Google captcha token, so why should Joomla start with it?

But that’s my personal opinion, others may have a different view.

I gave an two examples of situations, were countdown timer are used for signaling that a user have a time limit, I did not referred to the origin function of an 2FA authenticator or to check your bank account.

But these were the examples given, 2FA authenticator and bank account.

Anyway, maybe it’s just me not seing the need for a fix here, and as every human being I might be wrong.

Let’s wait for other opinions.

Invisible reCaptcha and V3 reCaptcha it is two totally different things.

The solution is to update reCaptcha to V3 or merge this #28798

Fedik,
I’m a bit confused here, the Issue is about «Invisible reCaptcha» not reCaptcha.
So «updating» make no sense, when you actually mean:

Switching to a different product, either «reCaptcha v3» or the product «hCaptcha» in the pr #26798 you mention.

That raises questions:
a) What about users, who want to or do use «Invisible reCaptcha»? User has to fix this issue by himself?
b) Or i do get you wrong and there is a «Invisible reCaptcha v3» and the version Joomla use is simply outdated?

Edit: I see, «Invisible reCaptcha» is based on reCaptcha v2, right? (by the look on the menu items at https://developers.google.com/recaptcha/docs/invisible)
So

the Issue is about «Invisible reCaptcha» not reCaptcha.

The issue about the timeout, with link to reCaptcha v3, that is incorrect.

btw, «reCaptcha v3» technically also «invisible», but it has a bit different api.

What about users, who want to or do use «Invisible reCaptcha»

User have to move to new version, at some point V2 will be dropped as was with V1

Источник

ReCAPTCHA validation failed due to: [‘timeout-or-duplicate’] #183

We get a lot of errors: «ReCAPTCHA validation failed due to: [‘timeout-or-duplicate’]»

Is there anyway to silence this error message?
Or can it be changed to a debug log?
As this just happens sometimes and our errors logs get filled with it.

The text was updated successfully, but these errors were encountered:

Having this error when some spam bots are trying to submit forms on my website. Also having ReCAPTCHA validation failed due to: [‘incorrect-captcha-sol’]

Same here, seeing this message in logs since some weeks. Running django-recaptcha==2.0.2.

We are also seeing this problem. I believe it is linked to fact that response tokens are only valid for 2 minutes.
See Google docs here.

  1. Load your page with the recaptcha v3 form
  2. Wait two minutes
  3. Submit the form
  4. Look for ReCAPTCHA validation failed due to: [‘timeout-or-duplicate’] in your logs

This is because the standard includes/js_v3.html template fetches the response token on page load. See this discussion about delaying getting to response token until the user actually submits the form.

Actually getting this error for many valid form submissions. The 2 minutes is not enough.

For a quickie fix I overrode templates/captcha/includes/js_v3.html and fixed up to update every 110 seconds:

@Gromph I cannot override the templates for some odd reason. Did exactly, what you suggest but it still uses to template from the pip module. It’s weird, because I am overriding lots of other templates from other third-party libs, just this one seems to be ignored. Did you encounter a similar issue?

@oesah Looks like what I did was make an app called «plaza-django-recaptcha»:

Then the app has just these 2 files:

just installed django-recaptcha and noticing this error — it appears that the error was a spammer account, but it would be nice if this doesn’t raise a server error. Any thoughts on an official fix from the dev team?

Anyone have one for v2 checkbox? This is what I’ve currently done, but I’m getting some console errors:

Источник

Verifying the user’s response

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:

For reCAPTCHA Android:

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.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Источник

Issue timeout-or-duplicate #31

I often (but not always..) get timeout-or-duplicate on first submit try, and on second submit the POST pass.
It seems it can happen when the validation process is run twice. Any idea ?

(Also, even if it fails, isn’t it suppose to fallback on V2 ? I thought it was suppose to, but i don’t see it anymore in README, maybe I mix up with some other project ?)

The text was updated successfully, but these errors were encountered:

Hello @Nuranto , I can answer «isn’t it suppose to fallback on V2» this question first, the v3 won’t fallback to v2 actually, v3 is only collecting score from your site action, and you determine your own score threshold. If the score less than threshold, you need to do your own fallback, the official site suggests to use v3 with two-factor authentication.

Yeah, in previous readme, this is included in TODO list, I removed it because it requires to load google script twice which doesn’t make sense and slow the site actually.

For your timeout-duplicate problem, can you briefly share your file arrangement? like how you manage to display the recaptcha v3 in blade or vue.

the official site suggests to use v3 with two-factor authentication.

In my case, I’m not using it for auth, but for contact and comment forms. But I see the idea.

Yeah, in previous readme, this is included in TODO list, I removed it because it requires to load google script twice which doesn’t make sense and slow the site actually.

Isn’t it possible to load V2 script only in case of failure ?

For your timeout-duplicate problem, can you briefly share your file arrangement? like how you manage to display the recaptcha v3 in blade or vue.

Источник

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

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.

Я получил контактную форму на своем веб-сайте в Laravel, и я хотел бы разместить ReCaptcha v3, но на данный момент в результате проверки я получил ошибку «timeout-or-duplicate».

Вы можете помочь мне от А до Я? Я не знаю куда идти…

Моя голова:

<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": '',
}

Я предполагаю, что проблема в том, что «метод post» используется два раза, потому что, когда я проверяю непосредственно на API Google, чтобы проверить токен пользователя, он показывает код, но сразу после обновления страницы он показывает мне «тайм-аут или дубликат», но Я не знаю как это исправить

  1. Home

  2. php — I got «timeout-or-duplicate» error using ReCaptcha v3

829 votes

5 answers

Get the solution ↓↓↓

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' => '[email protected]'));

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('[email protected]')->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

2022-04-13

Write your answer


652

votes

Answer

Solution:

As stated in the documentation this error is caused by:

  1. Validity time of the token expired (After you get the response token, you need to verify it within two minutes)
  2. Token has been used previously. To confirm that, log the token value before is used (error log, local file, whatever)

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

    });

Resolution for 2, fix your code :)


57

votes

Answer

Solution:

I got this from people double clicking the submit button on the form.


285

votes

Answer

Solution:

Every time the page reloads you get a new token from google . You can use that token only once . Somehow if you are using that token more than once to get the response from google Api , you will get that error . Check this error reference https://developers.google.com/recaptcha/docs/verify?hl=en


124

votes

Answer

Solution:

The problem is this piece of code:

<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 token is only valid for 2 minutes after youexecute is called as stated in the docs:

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.

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 callexecute if the user actually submits your form / takes action. In vanilla JS it would look like this:

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


683

votes

Answer

Solution:

I been googling looking for answers specifically similar to your use case.

reCaptcha V3 does not have reset API.

I solve the problem by when Password or Email authentication failed on your side, execute this again on your AJAX if failed. So that the value get replace with new g-token without reloading the site again, since following Google Documentation like me, the script execute on ready at your «signin page»

 grecaptcha.ready(function() {
              grecaptcha.execute('abhkdfhlasdfhldafhlashflasdhl', {action: 'submit'}).then(function(token) {
                document.getElementById('g-token').value = token;
              });
            });


Share solution ↓

Additional Information:

Date the issue was resolved:

2022-04-13

Link To Source

Link To Answer
People are also looking for solutions of the problem: filter_sanitize_string deprecated

Didn’t find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.


Similar questions

Find the answer in similar questions on our website.

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.


About the technologies asked in this question

PHP

PHP (from the English Hypertext Preprocessor — hypertext preprocessor) is a scripting programming language for developing web applications. Supported by most hosting providers, it is one of the most popular tools for creating dynamic websites.
The PHP scripting language has gained wide popularity due to its processing speed, simplicity, cross-platform, functionality and distribution of source codes under its own license.
https://www.php.net/

Laravel

Laravel is a free open source PHP framework that came out in 2011. Since then, it has been able to become the framework of choice for web developers. One of the main reasons for this is that Laravel makes it easier, faster, and safer to develop complex web applications than any other framework.
https://laravel.com/

JavaScript

JavaScript is a multi-paradigm language that supports event-driven, functional, and mandatory (including object-oriented and prototype-based) programming types. Originally JavaScript was only used on the client side. JavaScript is now still used as a server-side programming language. To summarize, we can say that JavaScript is the language of the Internet.
https://www.javascript.com/

HTML

HTML (English «hyper text markup language» — hypertext markup language) is a special markup language that is used to create sites on the Internet.
Browsers understand html perfectly and can interpret it in an understandable way. In general, any page on the site is html-code, which the browser translates into a user-friendly form. By the way, the code of any page is available to everyone.
https://www.w3.org/html/



Welcome to programmierfrage.com

programmierfrage.com is a question and answer site for professional web developers, programming enthusiasts and website builders. Site created and operated by the community. Together with you, we create a free library of detailed answers to any question on programming, web development, website creation and website administration.

Get answers to specific questions

Ask about the real problem you are facing. Describe in detail what you are doing and what you want to achieve.

Help Others Solve Their Issues

Our goal is to create a strong community in which everyone will support each other. If you find a question and know the answer to it, help others with your knowledge.


No Code Attached Yet


Information Required

  • Closed
  • 9 Feb 2022
  • Low
  • Build: master
  •  

    # 30644

  • Categories:
  • Plugins

if you spend more then 2 minutes on the account registration form (might be any other form which utilizes Invisible reCAPTCHA plugin) then on submitting the form you get an Error: «timeout-or-duplicate»
If you click one more time on Submit button that form should be submitted successfully.

This happens due to the captcha token is only valid for 2 minutes after execute is called as stated in the docs: https://developers.google.com/recaptcha/docs/v3

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.

Another possible solution: set an interval that calls the set token function, so it is refreshed every 2 minutes.

screen shot 2020-09-14 at 23 13 06


avatar macstalker
macstalker
— open
14 Sep 2020


avatar joomla-cms-bot
joomla-cms-bot
— labeled
14 Sep 2020

avatar jiweigert

avatar richard67

avatar jiweigert

avatar richard67

avatar jiweigert

avatar richard67

avatar jiweigert

avatar richard67

avatar Fedik

avatar Fedik

avatar jiweigert

avatar Fedik

avatar jiweigert


avatar Quy
Quy
— change
9 Feb 2022

Labels Added:
No Code Attached Yet


Information Required

Removed:
?


avatar Quy
Quy
— change
9 Feb 2022

Status New Closed
Closed_Date 0000-00-00 00:00:00 2022-02-09 20:12:47
Closed_By Quy

avatar Quy

Add a Comment

Login with GitHub to post a comment

Online spam is the most irritating thing which happens to site users. The problem is that you won’t be able to distinguish between a real user and a bot browsing through your site.
There is a solution for such to protect your site is to use Google Recaptcha V3 API which I’ll teach you in this post of how to protect against bots and spams using Google Recaptcha in Django Rest Framework.

Create Project And App in Django

Client-Side Integration

For Client-Side Integration, there are two ways of doing it. But both the ways are a bit different and here we’ll learn about both the ways.

1. Generating token Automatically

Here the captcha will automatically calculate on the basis of score and add the captcha token within the form when the user clicks the button. On the server side, you can access the token by the name g-recaptcha-response.

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

<form onsubmit="onSubmit( event )" id="contactus-form" method="post">
    <!-- here have your form fields -->

    <button 
    class="g-recaptcha" 
    data-sitekey="<recaptcha_clientside_secret_here>" 
    data-callback='onSubmit' 
    data-action='submit'>Submit</button>
</form>

<script>    
    function onSubmit(token) {
        document.getElementById("contactus-form").submit();
    }
</script>

2. Generating token Programmatically

In this step, you can decide when to invoke the captcha and receive token and this is also good for the custom requirements if you have any on those.

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

<form onsubmit="onSubmit( event )" id="contactus-form" method="post">
    <!-- here you will have response of recaptcha token -->
    <input type="hidden" name="recaptcha_token" id="recaptcha_token" value="" >

    <!-- here have your form fields -->

    <input type="submit" value="Submit">
</form>

<script>
    function onSubmit(e) {
        e.preventDefault();
        grecaptcha.ready(function() {
            grecaptcha.execute('<recaptcha_clientside_secret_here>', {action: 'submit'}).then(function(token) {
                // here fetch the token and add to form field
                document.getElementById('recaptcha_token').value = token;
                e.target.submit();
            });
        });
    }
</script>

Handling Token on Serverside

On the server side, you have to to a cURL request to https://www.google.com/recaptcha/api/siteverify with the serverside secret key.

Here is a sample working code in Python Django Framework.

import requests

serverside_secret = "<recaptcha_serverside_secret_here>"
url = "https://www.google.com/recaptcha/api/siteverify"
query = {
    "secret" : serverside_secret,
    "response" : request.POST.get('g-recaptcha-response') #if you are using generating token automatically
    #OR
    "response" : request.POST.get('recaptcha_token') #if you are using generating token Programatically
}
response = requests.post( url, data=query )
response_json = response.json()

The method response.json() will give you the JSON response and to verify if the response is correct to use the success key must be True.

Here is the sample success response in JSON.

{
    "success": true,
    "challenge_ts": "2022-01-12T19:15:43Z",
    "hostname": "127.0.0.1",
    "score": 0.9,
    "action": "submit"
}

Here there are two most important keys to look for they are:

  • success: This will return True if the response value is correct.
  • score: This ranges from 0 to 1 and 1 being accurate and 0 being considered as bot.

Note

The captcha response will only work once and if you try to send the response with the same token then you will receive a timeout-or-duplicate error and a similar response as shown below.

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

Integration Recaptcha with Django Framework

I’ll be using an example of the contact us form where I’ll implement Recaptcha.

In main app srcsettings.py

RECAPTCHA = {
    'clientside_secret' : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
    'serverside_secret' : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
    'verify_url' : 'https://www.google.com/recaptcha/api/siteverify'
}

In contactusforms.py

from django import forms
import requests
from django.conf import settings

def recaptcha_validator(value):

    query = {
        "secret" : settings.RECAPTCHA['serverside_secret'],
        "response" : value
    }

    response = requests.post( settings.RECAPTCHA['verify_url'], data=query )
    response_json = response.json()

    if response_json['success'] == False:
        error_str = "".join( response_json['error-codes'] )
        raise forms.ValidationError(f"Recaptcha Error : { error_str }")


class ContactForm(forms.Form):
    name  = forms.CharField(max_length=255, required=True, initial="", label="Name*", widget=forms.TextInput( attrs={ 'class' : 'form-control' } ))
    message  = forms.CharField(required=False, initial="", label="Message*", widget=forms.Textarea( attrs={ 'class' : 'form-control', 'rows' : 3 } ))
    phone_no  = forms.CharField(required=False, label="Phone no*" , widget=forms.TextInput( attrs={ 'class' : 'form-control' } ))
    recaptcha_token  = forms.CharField( initial="", validators=[recaptcha_validator] )

In contactusviews.py

from django.shortcuts import render, HttpResponse
from contactus.forms import ContactForm
from django.conf import settings

# Create your views here.
def form(request):
    info = {
        'form' : ContactForm(),
        'recaptcha_setting' : settings.RECAPTCHA
    }

    return render(request, 'contactus/form.html', info)

def save(request):
    info = {
        'form' : ContactForm(request.POST),
        'recaptcha_setting' : settings.RECAPTCHA
    }

    if info["form"].is_valid():
        return HttpResponse("All fields correct.")

    return render(request, 'contactus/form.html', info)
    

In contactustemplatescontactusform.html

<script src="https://www.google.com/recaptcha/api.js?render={{recaptcha_setting.clientside_secret}}"></script>

<div class="row">
    <div class="col-md-4 offset-md-4">
        
        {% if form.errors %}
            <div class="alert alert-danger" >
                <h4>Form Submission Errors</h4>
                <ul>
                    {% for index, error in form.errors.items %}
                        {{ error }} 
                    {% endfor %}
                </ul>
            </div>
        {% endif %}


        <h2 class="text-center" >Contact Form</h2>
        
        <form onsubmit="onSubmit(event)" action="{% url 'contactus:save' %}" method="post"  >
            {% csrf_token %}

            {{form.recaptcha_token.as_hidden}}
            
            <div>
                <label>{{ form.name.label }}</label>
                {{form.name}}
            </div>
            
            <div>
                <label>{{ form.message.label }}</label>
                {{form.message}}
            </div>

            <div>
                <label>{{ form.phone_no.label }}</label>
                {{form.phone_no}}
            </div>

            <div class="mt-10" >
                <input type="submit" class="btn btn-primary btn-block" value="Save">
            </div>
        </form>


    </div>
</div>

<script>
    function onSubmit(e) {
        e.preventDefault();
        grecaptcha.ready(function() {
            grecaptcha.execute('{{recaptcha_setting.clientside_secret}}', {action: 'submit'}).then(function(token) {
                document.getElementsByName('recaptcha_token')[0].value = token;
                e.target.submit();
            });
        });
    }
</script>

In contactusurls.py

from django.urls import path
from contactus import views
app_name = "contactus"

urlpatterns = [
    path( 'form', views.form, name="form" ),
    path( 'save', views.save, name="save" ),
]

Custom Validator to Check to validity

In contactusforms.py, I have created a custom validator to check whether the captcha token is valid to not, and also this code makes validation simpler and easier.

from django import forms
import requests
from django.conf import settings

def recaptcha_validator(value):

    query = {
        "secret" : settings.RECAPTCHA['serverside_secret'],
        "response" : value
    }

    response = requests.post( settings.RECAPTCHA['verify_url'], data=query )
    response_json = response.json()

    if response_json['success'] == False:
        error_str = "".join( response_json['error-codes'] )
        raise forms.ValidationError(f"Recaptcha Error : { error_str }")

Watch Video

Conclusion

This was all about Protect site against spam using Google Recaptcha and Integrating Google Recaptcha in Django Framework. Thank you for reading.

Понравилась статья? Поделить с друзьями:
  • Caps error removing stale connection because of ident conflict with
  • Cappsystemdict unable to load module client error 126
  • Cappsystemdict unable to load module client dependency of application error 193
  • Cappsystemdict unable to load module client dependency of application error 127
  • Cappsystemdict loadsystemanddependencies dota 2 ошибка 193