Thursday, September 15, 2011

The Play Framework - Part 5 - CAPTCHAs

The Play Framework is a MVC web application framework for Java that focuses on being light-weight and easy to use--two qualities that you don't see very often in the Java web application world.


Play comes packaged with a CAPTCHA generator, which is good for ensuring that form submissions are sent by a human being and not by an automated bot.

A CAPTCHA is an image that contains random letters and numbers that the user has to type in order to submit a form. The letters and numbers are rendered in a non-uniform way in order to make it as difficult as possible for an automated image recognition algorithm to read (but still clear enough for a human to read). For example, the characters may each be a different size and font. It stands for (take a deep breath) "Completely Automated Public Turing test to tell Computers and Humans Apart".

To generate a CAPTCHA in Play, use the Images.Captcha class:

public class Application extends Controller{
  public static void captcha(){
    Images.Captcha captcha = Images.captcha();
    String code = captcha.getText("#990000");
    captcha.addNoise("#CCCCCC");
    captcha.setBackground("#996633", "#FF9900");
    renderBinary(captcha);
  }
}

In this code, I'm generating a CAPTCHA image and returning it in the response. Calling the getText() method sets the color of the text and returns the random string that the CAPTCHA is rendering. As you can see, the notation used to define the color is conveniently the same notation that is used in HTML and CSS (however, you cannot use the three-character abbreviated form used by CSS).

I'm also adding noise to the image to make it even harder for an image recognition algorithm to read (it will add a gray squiggly line through the image). And then, I'm setting a background gradient to have it fade from a dark to a light orange.

Because the Captcha class implements InputStream, it can be passed into the renderBinary() method to send the image to the response. It generates a PNG image.

No comments: