challenge_response

challenge_response is a plugin for Ruby on Rails. It’s purpose is to replace CAPTCHA’s within web applications. The challenge_response plugin will ask the viewer a question such as “What does 1 + 1 equal?” or “What letter comes before D?”, appose to presenting a distorted image which the viewer must decipher.

The purpose of the challenge_response plugin is to ensure the data entered into the web application is in fact a human and not computer generated. A CAPTCHA does this, but anyone that has seen these distorted images knows exactly why they don’t like them. A simple addition or subtraction problem on the other hand is easy to read and even easier to answer. The best part of all is how easily the challenge_response plugin can be integrated into your projects.

The plugin is available at Github.com: http://github.com/daneharrigan/challenge_response/tree/master

Adding the challenge_response plugin

Lets add the plugin to our Rails project.


~$ script/plugin install git://github.com/daneharrigan/challenge_response.git

That was easy. Now lets generate the required files.


~$ script/generate challenge_response

That should have created the your migration file in db/migrate and your challenge questions and answers in vendor/plugins/challenge_response/challenge_questions.yml.

At this point you should review the questions in the challenge_questions.yml file to make sure there is enough variety and acceptable quality. In the event that you would like the regenerate challenge_questions.yml you just have to:


~$ script/generate challenge_response redo

And then we run the migration.


~$ rake db:migrate

This will not only create the tables challenges and challenged_sessions, but also enter the challenge_questions.yml data into the appropriate table as well.

So far its pretty straightforward.

Using the challenge_response plugin

The following code will use these 5 methods:

  • challenge_response
  • challenge_successful?
  • create_challenge
  • challenge_question
  • challenge_answer_tag

For this example I’ll use the controller “People.”

In the people_controllers.rb file include ChallengeResponse and add the before_filter:

1
2
3
4
5
class PeopleController < ApplicationController
  include ChallengeResponse
  before_filter :challenge_response, :for => [:new, :create]
  # ...
end

The ChallengeResponse module is included, making the methods available to the people controller. Next you’ll notice that the challenge_response method is being processed on the new and create action. When called on the new action the challenge is created. When called on the create action the challenge is then validated.

The new and create actions

The challenge_successful? method determines whether or not the answer was correct. The create_challenge method creates a new question if the original was not answered correctly. These two methods should be used within your create method.

1
2
3
4
5
6
7
8
9
10
11
12
class PeopleController < ApplicationController
  # ...
  def create
    if params[:person] and challenge_successful?
      # ...
    else
      create_challenge
      # ...
    end
  end
  # ...
end

The new action view

The methods challenge_question and challenge_answer are to be used within the view.

The challenge_question returns the question in plain text. This can be styled appropriately to fit your application.

The challenge_answer creates an text field with the name “challenge_answer.” This method can be passed the same arguments as text_field_tag.

1
2
3
4
5
6
7
<% form_for @person do |f| %>
  ...
  <p>
    <span><%= challenge_question %><span>
    <%= challenge_answer_tag %>
  </p>
<% end %>

You’re done!

That wasn’t too bad was it? I hope it’s useful!