recaptcha icon indicating copy to clipboard operation
recaptcha copied to clipboard

Invisible recaptcha and HTML required fields

Open geoffrey opened this issue 6 years ago • 7 comments

It seems that when using invisible_recaptcha_tags, the native HTML input attribute required is bypassed.

For a login/signup form it would be great to be able to first validate that the fields are not empty on the client side using required: "true" before challenging with recaptcha.

Am I missing a helper parameter?

geoffrey avatar Feb 14 '19 22:02 geoffrey

so the user will know to "fill out this invisible field" ? ... not sure how this works out ... I guess it would fail faster ... want to make a PR ?

On Thu, Feb 14, 2019 at 2:55 PM Geoffrey Tisserand [email protected] wrote:

It seems that when using invisible_recaptcha_tags, the native HTML input attribute required is bypassed.

For a login/signup form it would be great to be able to first validate that the fields are not empty on the client side using required: "true" before challenging with recaptcha.

Am I missing a helper parameter?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ambethia/recaptcha/issues/302, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAsZ3S-mpPlAGOxTvw_ItrCAM2P7AAGks5vNelqgaJpZM4a8mlM .

grosser avatar Feb 14 '19 23:02 grosser

    <%= form_for :user, url: login_path do |f| %>
      <div class="form-group">
        <%= f.label :email %>
        <%= f.email_field :email, class: "form-control", placeholder: "[email protected]", required: "true" %>
      </div>

      <div class="form-group">
        <%= f.label :password %>
        <%= f.password_field :password, class: "form-control", required: "true", pattern: ".{6,}" %>
      </div>

      <%= invisible_recaptcha_tags text: "Login", class: "btn btn-block btn-danger" %>
    <% end %>

If you consider this basic login form.

Expected behaviour:

  • The client side prevents the submission of the form if either the email or password input is empty due to the required: "true" HTML attribute on those inputs

Current behaviour:

  • The recaptcha is being triggered and then submit the form bypassing the required attributes.

Does that make more sense?

geoffrey avatar Feb 14 '19 23:02 geoffrey

Ah, so the issue is that existing required gets ignored ... try removing recaptcha and see if it works good then, just to make sure. It's definitely not disabled on purpose. Then I guess dig into the js here and if nothing pops up (like catch submit events), then check the official recaptcha for reports of that error.

grosser avatar Feb 15 '19 16:02 grosser

This problem is related with this form.submit() in the default callback, as it doesn't trigger the native HTML validation.

As it's stated in the spec, in the form submission algorithm:

  1. If the submitted from submit() method flag is not set, and the submitter element's no-validate state is false, then interactively validate the constraints of form and examine the result: if the result is negative (the constraint validation concluded that there were invalid fields and probably informed the user of this) then fire an event named invalid at the form element and then return.

So validation rules will only apply when the form is not submitted via the .submit() method.

Seems like the workaround is to manually validate the form and then programmatically invoke the recaptcha challenge, as suggested in the last example here: https://developers.google.com/recaptcha/docs/invisible

anpa avatar Mar 13 '19 18:03 anpa

could triggering a button press or so work ? ... please make a PR if you have a workaround in mind :)

grosser avatar Mar 14 '19 02:03 grosser

I also experienced this issue and worked around it by using a custom callback that calls checkValidity and reportValidity. Basic code outline:

function submit_with_validations () {
  var form = document.querySelector('form'); // probably need a more specific way to reference your form
  if (form.checkValidity()) {
    form.submit();
  } else {
    grecaptcha.reset();
    form.reportValidity();
  }
}

I was already using custom callbacks to deal with multiple forms on a page but I believe it'd be good to document this and include it in the default callback.

brandonaaron avatar Apr 30 '20 12:04 brandonaaron

I also experienced this issue and worked around it by using a custom callback that calls checkValidity and reportValidity.

Using 5.8.0 with v2 invisible this did not work. When the form is invalid then corrected and submitted the following error occurs:

Cannot contact reCAPTCHA. Check your connection and try again.

I ended up doing this using Recaptcha.configuration.site_key and Recaptcha.configuration.api_server_url.

sshaw avatar Aug 19 '21 03:08 sshaw