Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate reCAPTCHA V2 Java (Servlet)

This is an Q&A style post, which I'll post both the question and an answer. The main reason for this is that I spent quite a lot of time searching the easiest way to validate recaptcha V2. So I'm going to share my knowledge to avoid further time wastage of developers.

How to do a server side validation of Google reCAPTCHA V2 or Invisible reCAPTCHA with Java?

like image 993
Roshana Pitigala Avatar asked Dec 03 '17 19:12

Roshana Pitigala


People also ask

How do I fix reCAPTCHA validation failed?

Make sure your browser is fully updated (see minimum browser requirements) Check that JavaScript is enabled in your browser. Try disabling plugins that might conflict with reCAPTCHA.

How do I validate an invisible reCAPTCHA?

Invoking the reCAPTCHA verification programmatically can be achieved by rendering the challenge in a div with an attribute data-size="invisible" and programmatically calling execute. Create a div with data-size="invisible" . Call grecaptcha.execute from a javascript method. grecaptcha.execute();

What is a reCAPTCHA validation issue?

reCAPTCHA analyzes interactions with the website to detect if they are made by a human or some form of automated abuse. Sometimes, you may see a "failed reCAPTCHA check" error message while trying to create or amend your account. This means the website believes your actions may be those of a bot.


1 Answers

I'm using org.json library for this. Get the jar file from here or read the docs. Add the jar file to your project and import the following classes.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONObject;

Use the following method for validation.

/**
 * Validates Google reCAPTCHA V2 or Invisible reCAPTCHA.
 *
 * @param secretKey Secret key (key given for communication between your
 * site and Google)
 * @param response reCAPTCHA response from client side.
 * (g-recaptcha-response)
 * @return true if validation successful, false otherwise.
 */
public synchronized boolean isCaptchaValid(String secretKey, String response) {
    try {
        String url = "https://www.google.com/recaptcha/api/siteverify",
                params = "secret=" + secretKey + "&response=" + response;

        HttpURLConnection http = (HttpURLConnection) new URL(url).openConnection();
        http.setDoOutput(true);
        http.setRequestMethod("POST");
        http.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded; charset=UTF-8");
        OutputStream out = http.getOutputStream();
        out.write(params.getBytes("UTF-8"));
        out.flush();
        out.close();

        InputStream res = http.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(res, "UTF-8"));

        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        JSONObject json = new JSONObject(sb.toString());
        res.close();

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

Call the above method as shown below,

if(isCaptchaValid("enter_your_key_here", request.getParameter("g-recaptcha-response"))){
    //valid
}

Hope this helps. Cheers!


EDIT: Using the POST method to verify information as recommended by Google, is way more safer, however if you need the GET method version please refer the edit history.

Don't encode the params variable. You will always get the below response by doing so.

{"error-codes":["missing-input-response","missing-input-secret"],"success":false}
like image 159
Roshana Pitigala Avatar answered Oct 07 '22 06:10

Roshana Pitigala