user4133294
user4133294

Reputation:

Working example of new recaptcha with Rails?

Does anyone have a working example of Google's new recaptcha in a Rails app? Every guide I try to follow is either unclear or incomplete, and seems to use a different method.

Hand-rolled code would be preferable.


Work in Progress:

config/environments/production.rb:

  #...
  recaptcha_public_key= "[PUBLIC KEY]"
  recaptcha_private_key= "[PRIVATE KEY]"
end

config/environments/development.rb:

  #...
  recaptcha_public_key= "[PUBLIC KEY]"
  recaptcha_private_key= "[PRIVATE KEY]"
end

config/initializers/recaptcha.rb

Recaptcha.configure do |config|
  config.public_key  = Rails.application.secrets.recaptcha_public_key
  config.private_key = Rails.application.secrets.recaptcha_secret_key
  config.api_version = 'v2'
end

Upvotes: 21

Views: 20934

Answers (4)

Reinier Garcia
Reinier Garcia

Reputation: 1680

Complete Solution, Step by Step:

The other answers here are not working anymore, as the recaptcha gem has being updated, as you can check here. This is how I used recaptcha with my Rails 6 application, step by step.

Step # 1: place the gem in your Gemfile:

gem 'recaptcha'

If you are using the gems figaro (like in my case) or dotenv to store the Env variables, you need to place the recaptcha gem below the declaration of any of those two gems.

Step # 2: Get the recaptcha APY keys:

Go to the reCAPTCHA admin console page that belongs to Google, to obtain one reCAPTCHA API key for production and another one for development (later you will see why). Copy all that information in a safe place temporally. To have some order in that matter, as you may need several other recaptcha keys in the future, you should follow some kind of distinctive notation for the label of those recaptcha keys. For example in my case it was for my personal website, so I call them reiniergarcia_production and reiniergarcia_development.

You need to select there the specific kind of recaptcha you are going to use. One kind of recaptcha's API key won't work for another type of recaptcha. In my case I used the v2 Checkbox type (the one that says: 'I'm not a robot').

Step # 3: Store the recaptcha APY keys on rails:

In my case I was using Figaro to store my environment variables on rails, so this is what I typed at config/application.yml:

production:
  recaptcha_site_key: 'wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww'
  recaptcha_secret_key: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

development:
  recaptcha_site_key: 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
  recaptcha_secret_key: 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'

Step # 4: Add the Recaptcha initializer:

I added the the file config/initializers/recaptcha.rb and inside I placed:

Recaptcha.configure do |config|
  # New configuration format:
  config.site_key = Figaro.env.recaptcha_site_key
  config.secret_key = Figaro.env.recaptcha_secret_key
end

That's the new configuration. Notice that now it's site_key & secret_key (not public_key or private_key anymore). Figaro will load dynamically the proper key, depending of the environment. In my case I deployed to Heroku, but don't worry, as I will get there soon.

Step # 5: Place the recatcha tag in your form:

This is what I did in my case:

  <%= form_with(model: contact, local: true) do |form| %>
    <%= hidden_field_tag :return_to, return_to %>

    <%= form.text_field :name, placeholder: 'Name', autofocus: false %>
    <%= form.email_field :email, placeholder: 'Email', autofocus: false %>
    <%= form.text_field :subject, placeholder: 'Subject', autofocus: false %>
    <%= form.text_area :message, placeholder: 'Message', autofocus: false, disabled: false %>

    <div class="row">
      <div class="col-md-6">
        <div style="margin-top: 14px;">
          <%= recaptcha_tags %>
        </div>
      </div>

      <div class="col-md-6 submit-button">
        <%= form.submit "SEND", name: "send" %>
      </div>
    </div>
  <% end %>

Step 6: Style your recaptcha tag:

You might need to style the position and/or size of your recaptcha tag in your front-end (generated for the recaptcha_tags helper). This is what I did in my case:

I added the file app/assets/stylesheets/recaptcha_tags.scss with:

.g-recaptcha {
  transform: scale(0.6);
  transform-origin: 0 0;
}

It allows first to reduce the size of the recaptcha tag (very useful as the recaptcha tag usually is too large). In your case if you need to add further styling, you should place it there, and not mixed with the rest of your css code. The way of importing this styling file is by adding at app/assets/stylesheets/application.scss, the following:

// Imports the recaptcha_tags styling:
@import "recaptcha_tags";

SideNote: If you are going to use several layouts, you should have one main .scss file per each of them and on each of them you are going to import ONLY what's necessary for that particular layout (only those additional .scss strictly necessary).

Step # 7: Add the verify_recaptcha logic:

You need to add the verify_recaptcha logic in the proper action of your respective controller. In my case I wanted to persist a Contact object only if the user was "not a robot", so this is what I did at app/controllers/contacts_controller.rb:

  def create
    @contact = contact_service.build_contact(contact_params)

    if verify_recaptcha(model: @contact) && @contact.save
      redirect_notice = t('contacts.send.success_notice')
      redirect_to @return_to, notice: redirect_notice
    else
      flash[:alert] = @contact.errors.full_messages.first
      redirect_to @return_to
    end
  end

If the user doesn't click on "I'm not a robot", it will show a flash error on my page.

Step # 8: Place the env. variables in your server:

In my case as I said before, I was using Heroku. So I just went to my Dashboard in Heroku, then I clicked in my project, later in the Settings tab and then in a button that says: "Reveal Config Vars". And then I will added at the end the following pairs (key and value only):

  recaptcha_site_key: 'wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww'
  recaptcha_secret_key: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

As you can see, I only added the production recaptcha APY keys.

You can achieve the same from your terminal, by executing:

$ heroku config:set recaptcha_site_key=wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
$ heroku config:set recaptcha_secret_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Step # 9: Push all these changes to Github:

$ git push origin master

Step # 10: Deploy to Heroku again:

$ git push heroku master

And that's it. If you follow these steps you should have your recaptcha running perfectly on your production website too. I hope it was useful.

Upvotes: 0

sunnyrjuneja
sunnyrjuneja

Reputation: 6123

Using the recaptcha gem, I created an example that uses the check box method.

Code available here: https://github.com/sunnyrjuneja/recaptcha_example

The commits should be very easy to follow. Let me know if you have anymore questions.

Example application here: https://recaptcha-checkbox.herokuapp.com/

UPDATE:

Here's a way to do it without secrets.yml.

Change your initializer to look like this:

Recaptcha.configure do |config|
  config.public_key  = ENV['RECAPTCHA_PUBLIC_KEY']
  config.private_key = ENV['RECAPTCHA_PRIVATE_KEY']
end

In your development or production environment, add this to your .bashrc or .zshrc.

export RECAPTCHA_PUBLIC_KEY="YOURPUBLICKEY"
export RECAPTCHA_PRIVATE_KEY="YOURPRIVATEKEY"

If you're using Heroku to deploy do this on your command line:

heroku config:set RECAPTCHA_PUBLIC_KEY="YOURPUBLICKEY"
heroku config:set RECAPTCHA_PRIVATE_KEY="YOURPRIVATEKEY"

UPDATE 2:

The recaptcha gem now uses different method names for setting the keys.

Recaptcha.configure do |config| config.site_key = 'YOUR_SITE_KEY_HERE' config.secret_key = 'YOUR_SECRET_KEY_HERE' # Uncomment the following line if you are using a proxy server: # config.proxy = 'http://myproxy.com.au:8080' end

Upvotes: 41

Carma Tec
Carma Tec

Reputation: 41

You should try this example from RailsCarma's Blog.

Follow these steps: 1) Get the credentials 2) Add recaptcha tags 3) To handle verification, create a recaptcha class 4) In Registrations controller add verify_recaptcha method

Setup Step 1:-

Add the following to your gem file:

gem “recaptcha”, :require => “recaptcha/rails”

Step 2:-

Login to developers.google.com and sign into your gmail account and search for ‘recaptcha’. Click on “Signup for an API Key” link. Check the secret and site keys. As the name itself suggests, the secret key should be kept at a safer location whereas the site key is the public key used for authenticating to Google. Register your site name with your google account to retrieve public and private key that will be used later on the application.

After the registration is done, you will get the public key and private key. From the client side, the public key is sent to recaptcha service to request a new captcha. The private key is applied on the server side to verify if the right value is entered.

Then register for a reCAPTCHA API key and add that to your environment config files:

#put this in development.rb and in production.rb
ENV_RECAPTCHA_PUBLIC_KEY= ‘your-public-key’
ENV_RECAPTCHA_PRIVATE_KEY= ‘your-private-key’

Step 3:-

Create a file named recaptcha.rb in config/initializers to configure recaptcha parameters.
Recaptcha.configure do |config|
config.public_key = ‘ ENV_RECAPTCHA_PUBLIC_KEY’
config.private_key = ‘ENV_RECAPTCHA_PRIVATE_KEY’
config.proxy = ‘http://www.google.com/recaptcha/api/verify’
end

Step 4:- View

The Captcha Gem helps to render the actual captcha box. It’s as simple as putting the following into your view at the point where you want the captcha to appear:

<%= raw recaptcha_tags %>
If you are using SSL, use this instead:
<%= recaptcha_tags :ssl => true %>, The SSL option ensures we send a https request to the recaptcha service.

Step 5:- Controller

The Captcha Gem provides another helper method that posts to the reCaptcha API server to verify if the submission is correct. If it is then the method returns true, if not, it will add a custom error message that the recaptcha is wrong to the model instance. Here is the basic code as you might have it in the create action of your controller:-

In devise controllers, app/controllers/registrations_controller.rb, Insert the following code:

require ‘recaptcha.rb’
before_action :verify_recaptcha, only: [:create]
def verify_recaptcha
response = Recaptcha.verify(params)
session[:sign_up] = params[:user].except(:password, :password_confirmation, :remoteip)
if response.code == 200
if response[‘success’]
flash[:notice] = “Recaptcha verification successful.”
else
redirect_to new_user_registration_path(user: params[:user]),
alert: “Recaptcha verification error.”
end
else
redirect_to new_user_registration_path(user: params[:user]),
alert: “HTTP connection error.”
end
end

The session[:sign_up] is persisted as the signup form can be pre-filled if verification fails.

Upvotes: 1

Jenorish
Jenorish

Reputation: 1714

Please follow this:

Step 1. Create a Ruby on Rails application:-

a)Open a terminal, navigate to a directory where you have rights to create application and type: rails new recap

b)After you create the application, switch to its folder:

$cd recap

c)Type and run bundle install:

$bundle install

Step 2. Create models, views, and controllers:-

Step 3. Integrating Google Recaptcha With Ruby On Rails:-

a) Please login to Google Recaptcha website to register ur domain to get access.(https://www.google.com/recaptcha/intro/index.html)

b) Please login and register your site , with the details c)After registeration google provide the

Script tag place this snippet before the closing tag on your HTML template. div place this snippet at the end of the where you want the reCAPTCHA widget to appear.

d)Once the above steps are done, we can see the recaptcha in the site.

f)For the server side validation we can use the secret key and the response which is going to be sent as parameters to the form submit action in the controller.

g)To check whether Google has verified that user, send a GET request with these parameters:URL: https://www.google.com/recaptcha/api/siteverify

Step 4. Application Code change for server side validation.

Please see below links for more details,

1) recaptcha-in-rails

2) google-recaptcha-in-rails

In layout:

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

My view app/views/users/_form.html.erb:

<div class="g-recaptcha" data-sitekey="6LdgWwETAAAAAPwAddRqDtNbt9sdfsfsfsdJhggghhKKYTdadsHt54"></div>

In initializers:

SECRET_KEY = "my_secret_key_here"

In User Controller:

 def verify_google_recptcha(secret_key,response)
  status = `curl "https://www.google.com/recaptcha/api/siteverify?secret=#{secret_key}&response=#{response}"`
     logger.info "---------------status ==> #{status}"
     hash = JSON.parse(status)
     hash["success"] == true ? true : false
  end

  def create
    @user = User.new(user_params)
    status = verify_google_recptcha(SECRET_KEY,params["g-recaptcha-response"])
    respond_to do |format|
    if @user.save && status
      format.html { redirect_to @user, notice: 'User was successfully created.' }
      format.json { render :show, status: :created, location: @user }
    else
      format.html { render :new }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end
logger.info "---------------status ==> #{status}" will print like below

In Error:

---------------status ==> {
"success": false,
 "error-codes": [
  "missing-input-response"
 ]
}

In success

 ---------------status ==> {
"success": true
}

In that you could take status["error-codes"][0] and you could show it in _form.html.erb

See my application in heroku

Upvotes: 2

Related Questions