JavaServer Pages jQuery CAPTCHA Code Example
The JSP jQuery Captcha code example shows how to integrate jQuery Validation client-side form validation.
First Time Here?
Check the BotDetect JSP Captcha Quickstart for key integration steps.
It uses the Captcha Form Example as a starting point, and adds client-side jQuery Validation rules for all form fields.
Client-side validation is not secure by itself (it can be bypassed trivially), so the example also shows how the protected form action must always be secured by server-side CAPTCHA validation first, and use client-side validation only to improve the user experience.
Downloaded Location
The JSP jQuery CAPTCHA Example is included in examples
folder of the download package as bdc3-jsp-jquery-validation-captcha-example.war
file. Deploying (unpacking) the file will create a standard JSP directory tree.
index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib prefix="botDetect" uri="botDetect"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>BotDetect CAPTCHA jQuery validation Example</title> <link rel="stylesheet" href="stylesheet.css" type="text/css"/> <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script> <script type="text/javascript" src="js/jquery.validate.min.js"></script> </head> <body> <form id="form1" action="jqueryValidationAction" method="post"> <h1>BotDetect CAPTCHA jQuery validation Example</h1> <fieldset> <legend>CAPTCHA Validation</legend> <label for="captchaCodeTextBox" class="prompt"> Retype the code from the picture:</label> <!-- Adding BotDetect Captcha to the page--> <botDetect:captcha id="jqueryValidatedCaptcha" /> <div class="validationDiv"> <input id="captchaCodeTextBox" type="text" name="captchaCodeTextBox" class="captchaVal"/> <br> <input type="submit" name="validate" value="Validate" /> <label class="correct">${messages.captchaCodeCorrect}</label> <label class="incorrect">${messages.captchaCodeIncorrect}</label> </div> </fieldset> <script type="text/javascript" src="js/validation_rules.js"></script> </form> </body> </html>
The input form code is similar to Captcha tag example index.jsp
. Differences are that we must include jQuery, the jQuery.validate plugin and the script containing our custom validation rules. Also note that we use default userInputClientId
("captchaCodeTextBox
") instead customized as in aforementioned example.
validation_rules.js
$(document).ready(function() { $("#form1").validate({ // only validate fields when the form is submitted: // the Captcha input must only be validated when the whole code string is // typed in, not after each individual character (onkeyup must be false); // onfocusout validation could be left on in more complex forms, but // doesn't fit this example onkeyup: false, onfocusout: false, // customize client-side error display elements errorClass: "incorrect", validClass: "correct", errorElement: "label", // show the client-side error label to the left of the textbox errorPlacement: function(error, element) { $(".correct").text(""); offset = element.offset(); error.insertAfter(element); }, // always reload the Captcha image if remote validation failed, // since it will not be usable any more (a failed validation attempt // removes the attempted code for necessary Captcha security showErrors: function(errorMap, errorList) { this.defaultShowErrors(); for (var i=0; i<errorList.length; i++) { var element = errorList[i].element; var message = errorList[i].message; // check element css class and does the error message match remote // validation failure if (element.className.match(/captchaVal/) && message === this.settings.messages[element.id].remote) { element.Captcha.ReloadImage(); } } }, submitHandler: function(form){ form.submit(); } }); $(".captchaVal").rules('add', { required: true, remote: $(".captchaVal").get(0).Captcha.ValidationUrl, messages: { required: 'Required (client)', remote: 'Incorrect (client)' } }); });
To set up jQuery validation of a textbox taking Captcha code input, we do the following:
- Add validation rules specifying it as a required field, that also needs to be validated remotely when a value is entered; define error messages shown when these validation rules are triggered
- Disable
onkeyup
validation of the Captcha code, since we must validate the whole code and not the individual characters - Reload the Captcha image whenever remote Captcha validation fails
CAPTCHA jQuery Validation Rules and Error Messages
Since we're not using the input textbox Id for jQuery validation rules, we need to add them dynamically after the default validator has been initialized; that's why they're located after the $("#form1").validate({
call.
The expression for the remote Captcha validation Url can easily be read looking at dot-separated segments from right to left:
- The
ValidationUrl
property is part of the BotDetect client-side API, and is unique for each Captcha instance - The client-side BotDetect object can always be accessed through the Captcha property of the Captcha code textbox.
- We use the standard jQuery selector to access the textbox by Css class, and the .get(0) function call to get the underlying DOM element. This is needed because BotDetect adds the custom Captcha property to the DOM element directly, and the jQuery wrapper element returned by the jQuery selector doesn't include it.
Disabling Remote CAPTCHA Validation on Individual Character Input
Since BotDetect deletes the Captcha code stored on the server after failed validation of a particular Captcha instance, we must avoid validating the user input before the user finished typing in the whole Captcha code. The simplest way to achieve this is to disable onkeyup
validation completely (onkeyup: false
).
Reloading the CAPTCHA Image When Remote Validation Fails
Due to the above (failed validation invalidates the stored code for security purposes), we must also always reload the Captcha image when remote validation fails. Otherwise the user would be trying to correct his input based on an expired image, and couldn't pass Captcha validation at all.
We do this by customizing the jQuery.validate showErrors callback: beside the regular functionality (this.defaultShowErrors
), we also check that there is Captcha validation error (element.className.match(/captchaVal/
) and that the error message indicates a remote validation failure (message === this.settings.messages[element.id].remote
). If that is case, we call the ReloadImage()
function on the client-side Captcha object (accessed through the textbox element as explained above).
JQueryValidationAction.java
package botdetect.examples.jsp.jquery_validation; import botdetect.web.Captcha; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class JQueryValidationAction extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Map<String, String> messages = new HashMap<String, String>(); request.setAttribute("messages", messages); Captcha captcha = Captcha.load(request, "jqueryValidatedCaptcha"); // validate the Captcha to check we're not dealing with a bot boolean isHuman = captcha.validate(request, request.getParameter("captchaCodeTextBox")); if (isHuman) { // Captcha validation passed, perform protected action messages.put("captchaCodeCorrect", "Successful form submission (server)."); } else { // Captcha validation failed, show error message messages.put("captchaCodeIncorrect", "Incorrect! (server)"); } RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp"); dispatcher.forward(request, response); } }
We left the server-side Captcha validation in place, ensuring that any bots or users with JavaScript disabled have their input checked. For users with JavaScript enabled, errors in Captcha code input will be shown on the client without full form being POSTed to the server.
To run this example, botdetect.jar
must be in the classpath.
Please Note
BotDetect Java Captcha Library v4.0.Beta3.7 is an in-progress port of BotDetect 4 Captcha, and we need you to guide our efforts towards a polished product. Please let us know if you encounter any bugs, implementation issues, or a usage scenario you would like to discuss.
Current BotDetect Versions
-
BotDetect ASP.NET CAPTCHA
2019-07-22v4.4.2 -
BotDetect Java CAPTCHA
2019-07-22v4.0.Beta3.7 -
BotDetect PHP CAPTCHA
2019-07-22v4.2.5