This article goes over how you can add Google reCaptcha v3 to a Rails app and use it to verify a form submission.
I couldn't find any other how-to...
For further actions, you may consider blocking this person and/or reporting abuse
Did you run into any issues with Turbolinks doing it this way? I noticed the page with my form will only load the recaptcha if I refresh the page.
I tried wrapping the grecaptcha.ready function in a document.on(turbolinks:load) like this:
but to no avail. Any suggestions?
Hey did you ever figure this out? Running into
Uncaught ReferenceError: grecaptcha is not defined
and it's referencing a lot of Turbolinks links.Hey! Sorry for the late reply. It's been awhile but I think I ended up disabling turbolinks for that particular page and the code ran fine after that.
Check this out: github.com/turbolinks/turbolinks#d...
Hope that helps!
Ahh okay! I'll try that out, thank you so much!
Hey Steven, I did not have any issues with turbolinks doing it the way I wrote in the blog post. I unfortunately haven't tried it with a
document.on(turbolinks:load)
wrapper.The following line makes a GET request, right? Shouldn't it be a POST?
Net::HTTP.get_response(uri)
I'm sorry if the question doesn't make sense, I'm a newbie, feeling a bit lost...
Thanks again for the amazing post, though, very easy to follow!
Hmm, it does look like the Google documentation says to make a POST request...
Honestly, when I wrote this (and still now), I had a really hard time understanding how the ReCaptcha worked, so I had to reference some other articles. Those articles all used
Net::HTTP.get_response(uri)
to get back the verification response.You could try to make it a POST request instead and see how it works. I haven't tried it myself yet!
I'm implementing a reCAPTCHA currently. I believe it is supposed to be a POST request.
In fact, it's a little insecure to pass the secret key (and the token to a lesser extent) via a GET request. The query parameters at the end of the URL are encrypted in transit (so long as HTTPS is used,) but they can still show up in server logs, etc.
Doesn't apply here, but those query parameters also show up in browser history! GET should never be used to transmit sensitive information over the web.
Hi Felice, great article!
I'm handling my forms with ajax (remote: true) and I'm struggling to figure out how I can reset the recaptcha after a successful post. Any help would be appreciated :)
Thanks,
Ben
Hi Ben, thanks for reading!
Unfortunately, I've never done the resetting with ajax myself, so I can't give you any tips from my own experience. I was just checking out some other blogs and the google documentation, though, and you might be able to use the reCaptcha javascript api and reset it with
grecaptcha.reset(widgetId);
. This blog post mentions it but not sure if it works.I know this is a little late but I just had to solve this problem so hopefully my response can help someone else. Basically, since my form is a
create
action, I edited mycreate.js
file to update the token on failed submission. Here's how:Here's a portion of my form where I render a partial that include my captcha tag:
Here's the complete partial:
potential_clients/captcha_field
:Finally, in my
create.js
I do the following:This will re-render the portion of the form with the token and since it hits the helper function, a new token is generated!
Nice! Thank you so much for sharing your solution!
First of all
thanks!! for helpful article for google reCaprcha v3 for rails..
I need some help to apply of this document...
rails version of my system is 4.1.11 ( because app which I use, can run under rails 4.xx only)
So I cannot use credentials.yml.enc file
Instead of credentials.yml.enc I should use another secret file (for example , secret_key_base )
But I do not know how to change the line to make the program work normally in ApplicationController.
I'm sorry, please teach me.
Hi there! Thank for reading!
Well, secrets from Rails' credential system are read with code that look like this (for example):
Rails.application.credentials.dig(:recaptcha_secret_key)
. So, anywhere you seeRails.applications.credentials...
, you need to replace it with how the other secret file like secret_key_base reads those variables. I'm not exactly sure how to do it for Rails 4 though, so you would need to research about that.I have also used the
dotenv
gem before, which is very easy to use. You learn more about dotenv here. Basically, you make a file named.env
and register any secret keys you need there. Then read them with something likeENV['SECRET_KEY']
.Hope that helps a little bit >< Sorry I don't know enough about the Rails 4 way to do it!
Anyone noticing recaptcha failures with this approach? the problem is a reCaptcha v3 will time out after 2 minutes, so if your users take longer to fill in the form the recaptcha json will return error-codes timeout-or-duplicate with a score of 0. It might be better to call recaptcha_execute on form submit to avoid this problem.
This article was really helpful so thanks for writing it up.
To address this comment, when I get back error-codes timeout-or-duplicate I am not receiving any score in that response (and success is false). I only get a score in the response when success is set to true, so I think the fact that he put json['success'] && json['score'] will address this correctly.
One thing I did was to add error handling with a begin/rescue in verify_recaptcha? because there are a couple things in that method that can blow up.
Great article as I found the google Docs extremely lacking on how to set this up for any site much less a Rails site. They make a lot of assumptions that you'll just get the part they're completely glossing over, e.g. the hidden field and token assignment.
One mistake I think I found though is in the method recaptcha_execute you have a reference to RECAPTCHA_SITE_KEY which I'm guessing is actually supposed to be ENV['RECAPTCHA_SITE_KEY'] or a defined constant. This might trip up some people. :)
Yikes, nice catch! It was supposed to be a constant above the two methods. Now fixed! Thanks for pointing that out.
I had a hard time with the Google documentation too, which is a big reason why I wrote this post! Thank you for reading :D
Top drawer Felice, thanks so much!
Great post, simple to follow!