ambethia / recaptcha

ReCaptcha helpers for ruby apps
http://github.com/ambethia/recaptcha
MIT License
1.97k stars 440 forks source link

Invisible recaptcha and HTML required fields #302

Open geoffrey opened 5 years ago

geoffrey commented 5 years ago

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?

grosser commented 5 years ago

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 notifications@github.com 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 .

geoffrey commented 5 years ago
    <%= form_for :user, url: login_path do |f| %>
      <div class="form-group">
        <%= f.label :email %>
        <%= f.email_field :email, class: "form-control", placeholder: "bob@apple.com", 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:

Current behaviour:

Does that make more sense?

grosser commented 5 years ago

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.

anpa commented 5 years ago

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

grosser commented 5 years ago

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

brandonaaron commented 4 years ago

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.

sshaw commented 3 years ago

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.