I needed to get some sort of a captcha solution up and running with the rails project that i am working on. Looked around and sure enough there is a easy solution. reCAPTCHA! its popular and its seems solid. there were some plugins for rails that would making integrating it a breeze too!. But oh well usually things aren’t that easy for me
. Turns out all of the plugins that i came across don’t directly support rails 3. They are not either updated or maintained. See this is the problem with plugins. You got a ton of them for rails but rails updates so fast that most of the plugins are not up-to-date. Specially if its not one of the super star plugins. Anyways having plugins is good. Having ones that are not updated is much better than having none.
I could have got one of the available plugins and hacked it to work with rails. But me being lazy and all that. I figured i would just implement things my self, like reinventing the wheel
Its pretty simple though. Heres how i did it.
BTW look here for a list of available plugins.
1. First of all head to http://www.google.com/recaptcha and get your self registered. It should be straight forward. Obtain and remember your private and public keys.
2. Although i am not using a plugin i don’t want go against DRY completely. So add this piece of reusable code to your ApplicationController. In this set the RECAPTCHA_PRIVATE_KEY to your private key.
class ApplicationController < ActionController::Base protect_from_forgery protected RECAPTCHA_PRIVATE_KEY = 'PRIVATE_KEY'; #try and verify the captcha response. Then give out a message to flash def verify_recaptcha(remote_ip, params) responce = Net::HTTP.post_form(URI.parse('http://www.google.com/recaptcha/api/verify'), {'privatekey'=>RECAPTCHA_PRIVATE_KEY, 'remoteip'=>remote_ip, 'challenge'=>params[:recaptcha_challenge_field], 'response'=> params[:recaptcha_response_field]}) result = {:status => responce.body.split("\n")[0], :error_code => responce.body.split("\n")[1]} if result[:error_code] == "incorrect-captcha-sol" flash[:alert] = "The CAPTCHA solution was incorrect. Please re-try" elsif flash[:alert] = "There has been a unexpected error with the application. Please contact the administrator. error code: #{result[:error_code]}" end result end end3. Add a new partial to views/share and name it as _recaptcha.erb (or as whatever template type you use). This will contain the stuff that goes in to a view where you wants to actually put the captcha in. For ex if you wants to use captcha where users are posting comments. You would render this partial in that view. Put the following code in to it. in this user your public key in place of PUBLIC_KEY.
<%= javascript_include_tag "http://www.google.com/recaptcha/api/challenge?k=PUBLIC_KEY" %> <noscript> <iframe src="http://www.google.com/recaptcha/api/noscript?k=PUBLIC_KEY" height="300" width="500" frameborder="0"></iframe> <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea> <input type="hidden" name="recaptcha_response_field" value="manual_challenge"> </noscript><div id="captcha"> <%= render '/share/recaptcha' %> </div>4. In the controller action that handles the post request for the comment creation (continuing the above example) you can use the following helper method to see if the user was able to solve the captcha accurately or not. If not you can get a error message and display that to the user or do something else.
# POST /comments # POST /comments.xml def create @comment = Comment.new(params[:comment]) if verify_recaptcha(request.remote_ip, params)[:status] == 'false' @notice = "captcha incorrect" respond_to do |format| format.html { render :action => "new" } format.xml { renderml => @comment.errors, :status => :unprocessable_entity } end elsif respond_to do |format| if @comment.save format.html { redirect_to(@comment, :notice => 'Comment was successfully created.') } format.xml { render
ml => @comment, :status => :created, :location => @comment } else format.html { render :action => "new" } format.xml { render
ml => @comment.errors, :status => :unprocessable_entity } end end end end
5. Thats it!. I did a example project while writing this post. You can get it from http://github.com/thekindofme/recaptcha-rails3-noplugin-exampleHope this helps.





Thank you for this example, it works just fine!
Comment by tehif — October 22, 2010 @ 3:34 pm
thanks for the example !! That’s what I need.
Comment by art — February 6, 2011 @ 10:20 pm
[...] http://thekindofme.wordpress.com/2010/09/25/recaptcha-with-rails-3-without-plugins/ [...]
Pingback by Interessante Variante Recaptcha in Rails 3.0 einzubinden ohne Plugins zu verwenden | The Hidden Engine Blog — March 5, 2011 @ 4:39 pm