According to the Recaptcha docs the lifetime of a recaptcha token is 2 minutes. Retrieving the token on page load gives you only 2 minutes to complete and submit a form.

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 rather than on page load.

Comments

casey created an issue. See original summary.

casey’s picture

Status: Active » Needs review
StatusFileSize
new2.6 KB
jedihe’s picture

Status: Needs review » Reviewed & tested by the community

I just tested #2 and it works great:

Without the patch:

  • Submitting the form 2min after it's loaded caused it to fail antibot validation.

With the patch:

  • Token is retrieved on submit; no need to submit before 2 min.
  • A form submitted normally works.
  • Double clicking of the submit button doesn't seem to break the submission, as previous submissions show as cancelled in DevTools.
  • A form submitted via AJAX works.

Tested in Chrome 83.0.4103.61.

As for code review, just a minor coding standards find:

+++ b/js/recaptcha_v3.js
@@ -6,6 +6,51 @@
+    provisionRecaptchaTokenElements(self, false,function() {

", function"

jedihe’s picture

Status: Reviewed & tested by the community » Needs work
mrinalini9’s picture

Assigned: Unassigned » mrinalini9
mrinalini9’s picture

Assigned: mrinalini9 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new2.6 KB
new468 bytes

Updated patch #2 along with the changes suggested in #3, please review.

casey’s picture

Status: Needs review » Needs work

The non-ajax form solution doesn't work: form submissions won't contain the value of the triggering element. Still looking for a working solution.

jedihe’s picture

EDIT: confirmed, the triggering element is missing from the POST'ed form data :/.

@casey, are you fully sure of that? non-AJAX forms are working fine for me with #2:

1. I get the invisible reCaptcha check triggered when I try to submit the form, *before* the actual form submission is triggered.
2. The form submission contains the correct POST data (copied from DevTools/Network):

name: a@b.com
pass: 123
form_build_id: form--hQMhWA...
form_id: my_form
captcha_sid: 9876
captcha_token: -hfYGt5z....SOME-STRING
captcha_response: 03AGdB...VERY-LONG-STRING
jedihe’s picture

Assigned: Unassigned » jedihe

Let me take a stab at this; I'll try to replace the onSubmit handlers with the one to handle reCaptcha v3 validation, then restore the other handlers and do form.requestSubmit(trigger) in the callback.

casey’s picture

form.requestSubmit &SubmitEvent.submitter are not supported in IE

https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/request...

https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter

A polyfill that covers all situations doesn't seem possible...

jedihe’s picture

Oh, didn't check compatibility at the beginning... :(.

Is there any way to resolve the reCaptcha v3 in a synchronous manner for browsers not supporting requestSubmit() and .submitter? if that's possible, then the submission blocks until the token is resolved, then just let the submission flow continue as normal; now, for this to work, I'm assuming that the form submission picks up the new data, set on-the-fly.

jedihe’s picture

Assigned: jedihe » Unassigned
casey’s picture

Maybe we should just refresh the token every 60 seconds.

jedihe’s picture

Assigned: Unassigned » jedihe
jedihe’s picture

StatusFileSize
new3.83 KB
new1.81 KB

Alright, I managed to get 'op' parameter be preserved on non-AJAX submissions; I just injected a hidden input to mirror the submit button that was clicked, since formElement.submit() only ignores [type=submit] elements.

Quick checks on an AJAX submitted form showed it still working fine.

Tested on Chrome 83.

jedihe’s picture

Assigned: jedihe » Unassigned
jedihe’s picture

Updated patch to not assume a specific name attribute of the submit button.

jedihe’s picture

Status: Needs work » Needs review

@casey: although I considered your idea about refreshing the token every 60 seconds, I didn't try that approach since it would have required quite a big refactor of the patch. #17 was done trying to leverage the previous work as much as possible.

casey’s picture

StatusFileSize
new2.67 KB

This patch uses the approach of updating the tokens every 90 seconds.

@jedihe, I am afraid that blocking/delaying form submits will cause all kinds of issues, since we don't have total control over how forms are being submitted.

For example, form.submit() won't trigger a new submit event. Other code can no longer be sure if a form has been submitted.

The ajax solution seems to work fine, but then again, we can't be sure how a form is being submitted.

The only solution that I can come up with, is using a timer and fetch new tokens just (30 seconds should be enough to send an process requests) before they expire.

  • casey authored 8155f84 on 8.x-1.x
    Issue #3145790 by jedihe, casey, mrinalini9: Recaptcha token should not...
dench0’s picture

Status: Needs review » Fixed

Thanks, applied.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

khaled.zaidan’s picture

Could we please also get this done on the D7 version?

I'll do a patch shortly backporting the #19 for D7 and upload here.

dench0’s picture

Status: Closed (fixed) » Active

  • dench0 authored f9b755c on 8.x-1.x
    Issue #3145790 by dench0: Recaptcha token should not be retrieved on...
dench0’s picture

Status: Active » Fixed
jedihe’s picture

I can confirm #20 + #25 work for me, tested on D 8.9, in a form submitted via AJAX.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.