Sep 08 2008

How to use reCAPTCHA with CI

by Chris

ReCAPTCHA's quality is going downImage by mathowie via Flickr

SPAM… a nasty little four letter word. Could mean tasty meat in a can or could mean junk e-mails and form submissions clogging your server and taking up space in your inbox. We are all familiar with it and are engaged in a constant battle to stop it. In this tutorial I’m going to show you how to implement a popular 3rd party CAPTCHA service with your CodeIgniter application.

The commonly accepted approach of handling form SPAM is by using a CAPTCHA control on your forms. The good news is that CodeIgniter comes with it’s own built in CAPTCHA functionality included in the form of a plug-in. I’ve used their plug-in before and it works well. It takes a little bit to get it setup and working properly and requires it’s own database table but it gets the job done.

There is, however, another CAPTCHA tool which I have been using a lot lately called reCAPTCHA and I like it better. reCAPTCHA is a free hosted CAPTCHA service provided by Carnegie Mellon University and serving over 60 million CAPTCHAs a day. This service allows you to integrate a CAPTCHA control on your site quickly and easily without any database modifications or a lot of coding. Below are step-by-step instructions for integrating reCAPTCHA in your CI app.

Step 1 – Create a reCAPTCHA account

Before you can start working with reCAPTCHA you will first need to visit their website and create an account. Once you have filled out the form you will be logged in and prompted to enter your first site. Each site you wish to protect with reCAPTCHA needs to be entered in your account. This is because each site will get it’s own unique private and public keys which you will need to interact with the reCAPTCHA API. So, enter your domain name and click Create Key.

Once you have entered your domain you will now be presented with your public and private key. Take a minute to copy and paste those two long strings into a text document for later use. Be sure to keep track of which is which or else things won’t work properly.

Step 2 – Download the reCAPTCHA PHP library

Now that you have your keys, you will want to download the PHP library they provide for interacting with the reCAPTCHA API. The archive you download will contain two example files and a code file called recaptchalib.php. Once you have the archive, unzip it and move the recaptchalib.php file into your applications helpers folder.

Why a helper and not a library?

We could certainly turn what they provided us into a library, but that would involve changing some of the code they provided since they are not providing a class. The recaptchalib.php contains a number of functions which are meant to help while interacting with the API. Therefore, it fits the helper definition nicely.

Step 3 – Use the library in your project

Now that we have the code we can use it in our application. The first thing we need to do is display the CAPTCHA control on the form your trying to protect. So, first load the helper:

[lang=php]
$this->load->helper(‘recaptchalib’);
[/lang]

Now that we have access to the helper functions, we can use the recaptcha_get_html() function.

[lang=php]

[/lang]

You will want to place this function in your view where you want to display the form control. This function takes only one argument: the public key you received earlier when you added your site to your reCAPTCHA account. You can either add both the public and private keys as class variables to your current controller. Or, my preference is to add the public and private keys to a custom config file that I autoload throughout my entire app. That way I can use the control anyplace in my site without duplicating my keys.

Now that we have the control displaying on our form we need to add code to handle the validation.

[lang=php]

// Validate the captcha submission.
function val_recaptcha($string)
{
$resp = recaptcha_check_answer($this->config->item(‘recap_private’),
$_SERVER["REMOTE_ADDR"],
$this->input->post(“recaptcha_challenge_field”),
$this->input->post(“recaptcha_response_field”));

if(!$resp->is_valid) {
$this->validation->set_message(‘val_recaptcha’,'Your answer for the security question was incorrect, please try again.’);
return FALSE;
}
else {
return TRUE;
}
}

function process_form()
{
$this->load->library(‘validation’);
$this->load->helper(‘recaptcha_helper’);

$this->validation->set_error_delimiters(‘

  • ‘, ‘
  • ‘);

    // Validation rules.
    $rules['recaptcha_challenge_field'] = ‘required|callback_val_recaptcha’;
    $this->validation->set_rules($rules);

    // Validation field names (for display in error messages).
    $fields['recaptcha_challenge_field'] = ‘Security Question’;
    $this->validation->set_fields($fields);

    if($this->validation->run() == FALSE) {
    // display errors
    }
    else {
    // process submission
    }
    }

    ?>
    [/lang]

    In the above code we are using CI’s built in validation library to validate the CAPTCHA. You can of course add any additional rules or fields that are needed. I’ve created a custom validation function called val_recaptcha() which is called via a callback within the validation rules on the recaptcha_challenge_field field (which is created when we used the recaptcha_get_html() function above). This validation function uses the recaptcha_check_answer() function from the reCAPTCHA helper to check whether what the user submitted is correct or not.

    And that’s really all there is to it. You are now using the same CAPTCHA protection as Facebook and many other sites throughout the web.

    Wait… it’s RED! Can I make it look better?

    Absolutely, the reCAPTCHA website has detailed instructions for how to alter the look and feel of the reCAPTCHA form control. There are a number of pre-set themes which you can choose from or you can create your own.

    Reblog this post [with Zemanta]

    No related posts.


    5 Responses to How to use reCAPTCHA with CI

    1. Ryan January 4, 2009 at 2:43 am

      Where does that validation code belong? Within the captcha helper file?

      Also, what is the most efficient way to call it from within the controller during form validation? Beyond that, I had no issues using the tutorial you wrote to implement the ReCaptcha.

      I would note however that the helper file needs to be renamed to something like recaptcha_helper.php, as CI looks for helper files to have the _helper at the end of helper file names.

      Thanks…

    2. Chris January 4, 2009 at 12:29 pm

      Hi Ryan: by validation code, are you referring to the val_recaptcha() function? If so, that function needs to live in the controller you’re using it with. It’s being accessed by CI’s validation library via a callback and to my knowledge you can’t put validation functions elsewhere if your using callbacks (unless your using CI 1.7).

      The most efficient way I have found to validate the recaptcha control is the way I have shown above, by calling the custom validation function using CI’s validation library using a callback. That allows you to use CI’s built in validation functionality as opposed to writing something yourself (which would result in more code).

    3. Ryan January 4, 2009 at 7:55 pm

      I have gotten everything working as it is supposed to (and yes, I am using CI 1.7) But no matter what i type into the captcha field, it still comes back with the error flag you set that says, “Your answer for the security question was incorrect, please try again.”

      I am assuming that the captcha api public and private codes are being found by the captcha script, or else i would get an error message. i am not sure where i am going wrong. Any suggestions?

    4. Kurucu September 21, 2009 at 6:33 am

      Nice article – clear and easy to follow! Better than the current CI documentation on reCaptcha, I think!

      Thanks for taking the time to explain it.

    5. Stuart January 14, 2010 at 11:23 am

      Thanks very much, useful information.

    Leave a Reply

    Your email address will not be published.

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>