reCAPTCHA v2 in Java

In this example we will show you how to integrate Google’s reCAPTCHA v2 service in Java to a login page simulating an application that requests a username and password.

ยป See more examples

Google registration

The first step is to register the domain of your application on the Google page: https://www.google.com/recaptcha/admin#list

The administrator looks more or less like this:

Google’s reCAPTCHAv2 service allows you to add one or multiple domains. After adding yours, Google will provide you with a site key and a secret key as shown below:

These data will be used later.

Important: For this test we modified the configuration in the Google service to allow the use of localhost as a test domain.

We have created this example as a Web project in Maven with the help of NetBeans 8.2 and added the following dependencies:

        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>1.1.2</version>
        </dependency>

We will create the following files in our project:

  • index.jsp – It is the start JSP and where we will place the login, password and Captcha confirmation entries.
  • inputSuccessful.jsp – If the username, password and captcha test are correct, this welcome page will be displayed.
  • LoginServlet.java – Servlet with access control and logic.
  • VerifyRecaptcha.java – It is responsible for verifying the result of the captcha test with the Google service.

The first JSP – index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title>Homepage</title>
      <script src="https://www.google.com/recaptcha/api.js"></script>
   </head>
   <body>
      <form action="LoginServlet" method="post">
         <table>
            <tbody>
               <tr>
                  <td>
                     user:
                  </td>
                  <td>
                     <input type="text" name="user">
                  </td>
               </tr>
               <tr>
                  <td>
                     password:
                  </td>
                  <td>
                     <input type="password" name="password">
                  </td>
               </tr>
               <tr>
                  <td></td>
                  <td>
                     <div class="g-recaptcha" data-sitekey="6LchMm4UAAAAAChlkD00000000000tMEqNV_h"></div>
                  </td>
               </tr>
               <tr>
                  <td></td>
                  <td>
                     <input type="submit" value="Login">
                  </td>
               </tr>
            </tbody>
         </table>
      </form>
   </body>
</html>

It is important that in this startup file you replace the site key that you got in your registry.

<div class="g-recaptcha" data-sitekey="6LchMm4UAAAAAChlkD00000000000tMEqNV_h"></div>

Our second JSP – successfulEntry.jsp

It only shows a welcome text and a link to the home page.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta charset="UTF-8">
        <title>Homepage</title>
    </head>
    <body>
        <h3>Welcome</h3>
        <a href="index.jsp">Homepage</a>
    </body>
</html>

The servlet that controls access – LoginServlet.java

Now it is necessary to create the servlet, for which we use the NetBeans Wizzard, but finally we modify the code as follows:

package com.geekole.servlet; // Name of your java package

import com.geekole.utils.VerifyRecaptcha;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author geekole.com
 */
@WebServlet(name = "LoginServlet", urlPatterns = {"/LoginServlet"}, initParams = {
    @WebInitParam(name = "user", value = "geekole"),
    @WebInitParam(name = "password", value = "123") })
public class LoginServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String user = request.getParameter("user");
        String password = request.getParameter("password");
        
        String gRecaptchaResponse = request.getParameter("g-recaptcha-response");
        System.out.println(gRecaptchaResponse);
        
        boolean verified = VerifyRecaptcha.verify(gRecaptchaResponse);

        String userRegistered = getServletConfig().getInitParameter("user");
        String passwordRegistered = getServletConfig().getInitParameter("password");

        System.out.println("user: " + user);
        System.out.println("password: " + password);
        System.out.println("captcha: " + verified);

        if (userRegistered.equals(user) && passwordRegistered.equals(password) && verified) {
            response.sendRedirect("successfulEntry.jsp");
        } else {
            RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
            PrintWriter out = response.getWriter();
            if (verified) {
                out.println("<span style="color: red;">The username or password is incorrect.</span>");
            } else {
                out.println("<span style="color: red;">Incorrect captcha.</span>");
            }
            rd.include(request, response);
        }
    }
}

This Servlet does some interesting things. Verify that the username and password are correct. But the most important thing is the use of the VerifyRecaptcha class to confirm through the Google service that the result of the captcha test has been successful.

The class – VerifyRecaptcha.java

package com.geekole.utils; // Name of your java package

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;

import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.net.ssl.HttpsURLConnection;

/**
 *
 * @author geekole.com
 */
public class VerifyRecaptcha {

    public static final String url = "https://www.google.com/recaptcha/api/siteverify";
    public static final String secret = "6LchMm4UAA00000000000b0ewwbuU2o-0";
    private final static String USER_AGENT = "Mozilla/5.0";

    public static boolean verify(String gRecaptchaResponse) throws IOException {
        if (gRecaptchaResponse == null || "".equals(gRecaptchaResponse)) {
            return false;
        }

        try {
            URL obj = new URL(url);
            HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", USER_AGENT);
            con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

            String postParams = "secret=" + secret + "&response=" + gRecaptchaResponse;

            con.setDoOutput(true);
            DataOutputStream wr = new DataOutputStream(con.getOutputStream());
            wr.writeBytes(postParams);
            wr.flush();
            wr.close();

            int responseCode = con.getResponseCode();
            System.out.println("Sending 'POST' peticion a URL : " + url);
            System.out.println("Parameters post : " + postParams);
            System.out.println("Response code : " + responseCode);

            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            System.out.println(response.toString());

            JsonReader jsonReader = Json.createReader(new StringReader(response.toString()));
            JsonObject jsonObject = jsonReader.readObject();
            jsonReader.close();

            return jsonObject.getBoolean("success");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

In VerifyRecaptcha, just like in the startup JSP, you need to replace the secret key that was generated during registration. In this class, the query is made with the Google service. A response is generated on the home page as a result of the captcha test.

String gRecaptchaResponse = request.getParameter(“g-recaptcha-response”);

This response is sent back to the Google service “https://www.google.com/recaptcha/api/siteverify”, the service evaluates if the captcha test has been successful and if so returns a confirmation response.

If you run the web application by deploying to Tomcat you will have the following output:

By clicking on the checkbox “I’m not a robot” the test will start and it will be as difficult or as easy, depending on how you configure its difficulty in the Google service manager.

If the visitor passes the reCAPTCHAv2 test, the component will display a success confirmation.

By clicking on “Login” the servlet is responsible for processing the request and will show you a simple welcome screen.

If the user bypasses the reCAPTCHAv2 test, then an error message will be displayed.

As you can see, it is very simple to implement this service of reCAPTCHA v2 in Java. The VerifyRecaptcha class may seem complicated, but you won’t have to modify it too much. Do not forget that Google frequently updates and improves its services. The domain management service may not look the same in the future.