Sunday, September 15, 2013
Today I am going to show you how you can generate and validate captcha. A CAPTCHA (an acronym for "Completely Automated Public Turing test to tell Computers and Humans Apart"), a trademark of Carnegie Mellon University, is a type of challenge-response test used in computing to determine whether or not the user is human. This requires the user to type the letters of a distorted image, sometimes with the addition of an obscured sequence of letters or digits that appears on the screen. Because the test is administered by a computer, in contrast to the standard Turing test that is administered by a human, a CAPTCHA is sometimes described as a reverse Turing test. This test is most common when someone registers or opens a new account in any website.
       Here we will be using jcaptcha library for captcha generation and validation. In our demo we will follow MVC architecture to carry this out. We have the following classes, servlets and JSPs in our project.

  • login.jsp : This is the home page. Here the captcha challenge image will be shown with a text-box to enter the characters.  On submitting it is validated by a servlet.
  • CaptchaService class : This is a singleton class that is responsible for generating the instance that will help in generating the challenge image.
  • CaptchaGeneratorServlet class : this servlet has a GET method which generates the image with CaptchaService class and converts it to a byte array and then writes to the output stream. The image is generated using the session id of the user which is used as the captcha id.
  • CaptchaVerifierServlet class : It has a POST method which receives the input characters from usere and validates it. The result is returned as a boolean which is set as a session attribute and for the result to be shown it is forwarded to a JSP.
  • results.jsp : It extracts the session attribute and displays result according to that.


-------------------------------------------------------------------------------------------------------------------------
Java Source Code
-------------------------------------------------------------------------------------------------------------------------
/* Code for login.jsp */
<!DOCTYPE html>
<html>
<head>
<title>JCaptcha Demo</title>
</head>
<body>
   <h2>JCaptcha Demo</h2>
   <form action="captcha-verifier" method="post">
      <input type="hidden" name="captchaID" value="<%= session.getId() %>"/>
      <table><tr>
           <td valign="middle">Enter these letters:<br/>
           <img src="./captcha-generator" align="middle" alt="Enter the 
             characters appearing in this image" border="1"/></td>
           <td><input type="text" name="inChars"/></td>
         </tr>
         <tr>
           <td><input type="submit" value="Submit"/></td>
         </tr>
      </table>
   </form>
</body>
</html>


/* Code for CaptchaService.java */
package java_code_house.jcaptcha;

import com.octo.captcha.service.image.ImageCaptchaService;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;

public class CaptchaService{
    // a singleton class
    private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService();
    
    public static ImageCaptchaService getInstance(){
     return instance;
    }

}



/* Code for CaptchaGeneratorServlet.java */
package java_code_house.jcaptcha;

import com.octo.captcha.service.CaptchaServiceException;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/captcha-generator")
public class CaptchaGeneratorServlet extends HttpServlet{
 private static final long serialVersionUID=1L;
 
 protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
  ByteArrayOutputStream imgStream = new ByteArrayOutputStream();
  byte[] captchaBytes=null;

   try{
   // Session ID is used to identify the particular captcha
   String captchaId = request.getSession().getId();
   // Generate the captcha image
   BufferedImage img = CaptchaService.getInstance().getImageChallengeForID(
     captchaId, request.getLocale() );
   ImageIO.write(img, "jpeg", imgStream );
   captchaBytes = imgStream.toByteArray();

    // Clear any existing flag
   request.getSession().removeAttribute("result");
  }catch( CaptchaServiceException|IOException ex ) {
   System.out.println(ex);
  }

   // Set appropriate http headers
  response.setHeader( "Cache-Control", "no-store" );
  response.setHeader( "Pragma", "no-cache" );
  response.setDateHeader( "Expires", 0 );
  response.setContentType( "image/jpeg");

   // Write the image to the client
  OutputStream os = response.getOutputStream();
  os.write(captchaBytes);
  os.flush();
  os.close();
 }

}



/* Code for CaptchaVerifierServlet.java */
package java_code_house.jcaptcha;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.octo.captcha.service.CaptchaServiceException;

@WebServlet("/captcha-verifier")
public class CaptchaVerifierServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  // Get the request params
  String cId = request.getParameter("captchaID");
  String inChars = request.getParameter("inChars");

   // Validate whether input from user is correct
  boolean hasPassed = validateCaptcha(cId, inChars );
  
  // Set flag into session
  request.getSession().setAttribute( "result", new Boolean(hasPassed) );

   // Forward request to results page
  request.getRequestDispatcher( "/results.jsp" ).forward( request, response );
 }

  private boolean validateCaptcha( String captchaId, String inputChars ){
  boolean b = false;
  try{
   b = CaptchaService.getInstance().validateResponseForID( captchaId, inputChars );
  }catch( CaptchaServiceException cse ){}
  return b;
 }

}



/* Code for results.jsp */
<!DOCTYPE html> 
<html>
<head>
<title>JCaptcha Demo - Result</title>
</head>
<body>
    <% Boolean b = (Boolean)session.getAttribute("result");
        if ( b!=null && b.booleanValue() ){
    %>
             Congrats!  You passed the Captcha test!
    <% } else { %>
             Sorry, you failed the Captcha test.
    <% } %>
</body>
</html>

-------------------------------------------------------------------------------------------------------------------------
Download Links
-------------------------------------------------------------------------------------------------------------------------
NOTE : While exporting the project from eclipse, optimization for Apache Tomcat v7 was done. Also it includes the source files as well as the jar files required to execute this.

Happy coding :)

8 comments:

  1. ARE YOU SURE IT WORK?

    ReplyDelete
  2. The image doesn't load.

    ReplyDelete
    Replies
    1. It might be due to some other reasons. The code is fine and tested before posting. Try downloading the WAR from link given in post and test

      Delete
  3. Oh men, thank so much, you helped me alot

    ReplyDelete

Total Pageviews

Subscribe via Email

Followers


Popular Posts

About Me

My photo

I am a student of BTech Computer Science Engineering from RCCIIT,Kolkata. I am a crazy lover of Java and wants to settle as a Java developer. I have a seven years Java experience with an application developer experience for 2 years. Recently from March 2012 I am a registered S40 app developer for Nokia and has corrected an app of them. I am currently writing blogs to encourage and grow interest in all those who don't know or learning Java.