Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

ReCaptcha for Rails - With AJAX Validation


This plugin implements view helpers to generate ReCaptcha code, to interface with the HTTP API for captcha verification, a DSL to generate a before_filter and the necessary hacky code to implement AJAX captcha validation.


For AJAX validation, a request to ReCaptcha HTTP server must be made in order to verify the user input, but captchas can be checked only once.

The plugin, thus, in case of a successful verification, saves uses the Rails flash to temporarily save this status in the session and then the before filter skips the verification via the ReCaptcha HTTP service.


Via RubyGems:

gem install panmind-recaptcha

Or via Rails Plugin:

rails plugin install git://


In your config/environment.rb:

  :private_key => 'your private key',
  :public_key  => 'your public key'

In your controller, say, the UsersController for a signup action:

require_valid_captcha :only => :create

  def invalid_captcha
    @user = params[:user]
    @user.errors.add_to_base('Captcha failed')

    render :new, :layout => 'login'

The invalid_captcha method is called by the plugin when captcha verification fails, and must be overwritten or a NotImplementedError exception will be thrown.

In your view:

<%= recaptcha :label => 'Are you human?', :theme => 'clean' %>

You can pass any RecaptchaOptions valid option, as stated by the service documentation. The only nonstandard option :label is used by the plugin to print a label before the captcha widget.

AJAX Validation

To cache the results of a successful captcha verification, you need simply to pass the :ajax => true option to the require_valid_captcha controller method.

require_valid_captcha :only => :create, :ajax => true

When the form is validated via AJAX, the maybe successful result will be saved in the flash (thus set in the session store); when the form is then submitted via a plain HTTP request, verification will be skipped.

On Panmind we use our jquery.ajax-validation plugin, that you can download from and the Javascript code located in the js/signup-sample.js file.

On the backend, an example checker that returns different HTTP status code follows:

def signup_checker
  # If no email was provided, return 400
  if params[:email].blank?
    render :nothing => true, :status => :bad_request and return

  email = CGI.unescape(params[:email])

  # more thorough checks on email should go here

  # If an user with this email already exist, return 406
  if User.exists?(['email = ?', email])
    render :nothing => true, :status => :not_acceptable and return

  unless valid_captcha?
    invalid_captcha and return

  save_solved_captcha # This method sets a flag in the flash
  render :nothing => true, :status => :ok

Moreover, the client Javascript code should be informed via an HTTP status when validation fails, thus the invalid_captcha must contain a special render when the request comes from XHR:

def invalid_captcha
  # If the captcha is not valid, return a 412 (precondition failed)
  render :nothing => true, :status => 412 and return true if request.xhr?

  # Same invalid_captcha code as above

The latest XHR specification from the w3c states that cookies set by responses to requests sent via XHR are to be honored by the browser.

The code was tested with IE (6,7,8), Safari (4, 5), Firefox 3, Chrome 5 and Opera 10.


As long as you use a session store backed on the server or cryptographically sign the cookies used by the session cookie store (as Rails does by default) there is no way to bypass the captcha when AJAX validation is enabled.


Tested with Rails 3.0.3 running under Ruby 1.9.2p0. running under Ruby 1.9.1-p378.


ReCaptcha plugin for Rails with AJAX validation support






No packages published