Languages
[Edit]
EN

reCAPTCHA v3 - simple example how to use in JavaScript and Spring Framework

19 points
Created by:
Root-ssh
177980

In this article we would like to show how to use Google reCAPTCHA v3 with JavaScript and Spring Framework (in Java).

The article consists of 3 parts:

  • Google reCAPTCHA v3 panel configuration example,
  • front-end code example,
  • back-end code example.

Official documentation of reCAPTCHA v3 can be found here.

 

Simple steps

  1. configure Google reCAPTCHA:
    1. go to Google reCAPTCHA panel
      https://www.google.com/recaptcha/admin#list
    2. create new configuration,
    3. type required data (check below screenshot):
      1. Label (configuration name),
      2. reCAPTCHA type as v3,
      3. Domain as my-domain.com and localhost for development,
    4. accept terms and Submit,
  2. integrate example codes with yours web site,
    1. copy source codes from the next sections,
    2. copy site key into index.html file (replace 2 times site_key_xxyyzz text - in script url and in variable):
      <script src="https://www.google.com/recaptcha/api.js?render=site_key_xxyyzz"></script>
      var PUBLIC_KEY = 'site_key_xxyyzz';
    3. copy secret key into ReCAPTCHAv3Utils.java file:
      private static final String SECRET_KEY = "secret_key_xxyyzz";
  3. open in web browser your web page and check if everything is working correctly.

Notes:

  • protect yours secret key!
  • set double SCORES_LEVEL = 0.7 according to yours requirements (read comment in code)
  • sometimes it is good to do some action if bot behaving is detected (e.g. wait 60 seconds or confirm if you are not bot with yours email).

 

Google reCAPTCHA v3 panel example 

In this section we want to show example configuration for reCAPTCHA v3. Pay attention on localhost domain if you want to develop yours application with active reCAPTCHA.

reCAPTCHA v3 registration.
reCAPTCHA v3 registration.
site key + secret key for reCAPTCHA v3
site key + secret key for reCAPTCHA v3

 

Front-end with JavaScript example

In this section login action was used to present reCAPTCHA v3 usage with JavaScript. But we can change login string to anything different (check: ReCAPTCHAv3Utils.request('login', onSuccess, onError)).

index.html file:

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
  <!-- reCaptcha v3 key to get on https://www.google.com/recaptcha/admin#list -->
  <script src='https://www.google.com/recaptcha/api.js?render=site_key_xxyyzz'></script>
</head>
<body>
  <script>

    /*
        reCaptcha v3 management:
            https://www.google.com/recaptcha/admin#list

        reCaptcha v3 documentation:
            https://developers.google.com/recaptcha/docs/v3
    */
    var ReCAPTCHAv3Utils = new function() {

        // reCaptcha v3 key to get on https://www.google.com/recaptcha/admin#list
        var PUBLIC_KEY = 'site_key_xxyyzz';

        // Requests Google reCAPTCHAv3 API to get token.
        //
        // argument:
        //     action - we can use own label that describes our action
        //         Look on "Use case" on the https://developers.google.com/recaptcha/docs/v3
        //         e.g. homepage, login, social, e-commerce
        //     onSuccess and onError - callback functions
        //
        this.request = function(action, onSuccess, onError) {
            if (window.grecaptcha) {
                window.grecaptcha.ready(function() {
                    var config = {
                        action : action
                    };
                    try {
                        var query = window.grecaptcha.execute(PUBLIC_KEY, config);
                        if (onSuccess) {
                            query.then(onSuccess);
                        }
                    } catch (e) {
                        var message = e && e.message || 'Captcha request error.';
                        if (onError) {
                            onError(message);
                        }
                    }
                });
            } else {
                if (onError) {
                    onError('reCAPTCHA v3 is not loaded correctly.');
                }
            }
        };
    };
    
    
    // Usage example:

    function loginUser(data) {
        var onSuccess = function(token) {
            data.token = token; // <------- token received from Google reCAPTCHA v3
            $.ajax({
                type: 'POST',
                url: '/backend/login-user',
                data: JSON.stringify(data),
                contentType : 'application/json; charset=utf-8',
                dataType : 'json',
                success: function(data) {
                    alert('Response: ' + data.message);
                },
                error: function(error) {
                    alert('Request error!');
                }
            });
        };
        var onError = function(message) {
            alert('Error: ' + message);
        };
        ReCAPTCHAv3Utils.request('login', onSuccess, onError);
    }

    loginUser({
        username: 'John',
        password: 'my-password-here'
    });

  </script>
</body>
</html>

 

Back-end with Spring Framework example

In this section, we can find all necessary files that are required to use reCAPTCHA v3 with Spring Framework.

It is necessary to create few files in a project and paste them content - the files are listed below.

pom.xml file (maven dependences):

<!-- Jackson JSON Mapper -->
<dependency>
	<groupId>org.codehaus.jackson</groupId>
	<artifactId>jackson-mapper-asl</artifactId>
	<version>1.9.10</version>
</dependency>

UserController.java file:

package logic.controller_captcha;

import logic.util.LoggerUtil;
import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import logic.controller_captcha.recaptchav3.ReCAPTCHAv3Exception;
import logic.controller_captcha.recaptchav3.ReCAPTCHAv3Utils;
import logic.controller_captcha.recaptchav3.ReCAPTCHAv3Response;

@Controller
public class UserController {

    private final Logger logger = Logger.getLogger(getClass());

    // from 0.0 to 1.0
    //  1.0 is very likely a good interaction
    //  0.0 is very likely a bot
    private final static double SCORES_LEVEL = 0.7;

    @RequestMapping(value = "/backend/login-user", method = RequestMethod.POST)
    @ResponseBody
    public String loginUser(
            HttpServletRequest request, 
            @RequestBody LoginUserRequest loginUserRequest
    ) {
        String token = loginUserRequest.getToken();
        String address = request.getRemoteAddr();
        try {
            ReCAPTCHAv3Response response = ReCAPTCHAv3Utils.request(token, address);
            if (response.getSuccess()) {
                if (response.getScore() > SCORES_LEVEL) {
                    // some login operation here ...
                    return "{\"message\": \"LOGIN SUCCESS\"}";
                } else {
                    return "{\"message\": \"STRANGE BEHAVING DETECTED\"}";
                }
            }
            return "{\"message\": \"ADDRESS OR TOKEN INCORRECT\"}";
        } catch (ReCAPTCHAv3Exception e) {
            return "{\"message\": \"CAPTCHA ERROR\"}";
        }
    }
}

LoginUserRequest.java file:

package logic.controller_captcha;

public class LoginUserRequest
{
    private String token;


    // other fields here ...


    public String getToken() {
        return this.token;
    }

    public void setToken(String token) {
        this.token = token;
    }
}

ReCAPTCHAv3Utils.java file:

package logic.controller_captcha.recaptchav3;

import org.codehaus.jackson.map.ObjectMapper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/*
    reCaptcha v3 management:
        https://www.google.com/recaptcha/admin#list

    reCaptcha v3 documentation:
        https://developers.google.com/recaptcha/docs/v3
*/
public final class ReCAPTCHAv3Utils {

    private static ObjectMapper mapper = new ObjectMapper();

    // reCaptcha v3 key to get on https://www.google.com/recaptcha/admin#list
	private static final String SECRET_KEY = "secret_key_xxyyzz";

    private ReCAPTCHAv3Utils() {
        // nothing here ...
    }

    private static String readStream(InputStream stream) throws IOException {
        StringBuilder builder = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
            while (true) {
                String line = reader.readLine();
                if (line == null) {
                    break;
                }
                builder.append(line);
            }
        }
        return builder.toString();
    }

    private static ReCAPTCHAv3Response readObject(InputStream stream) throws IOException {
        String response = readStream(stream);
        return mapper.readValue(response, ReCAPTCHAv3Response.class);
    }

    public static ReCAPTCHAv3Response request(String token, String ip) throws ReCAPTCHAv3Exception {
        try {
            URL url = new URL("https://www.google.com/recaptcha/api/siteverify?secret=" 
                + SECRET_KEY + "&response=" + token + "&remoteip=" + ip);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            try {
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(10000);
                connection.setReadTimeout(10000);
                return readObject(connection.getInputStream());
            } finally {
                connection.disconnect();
            }
        } catch (Exception e) {
            throw new ReCAPTCHAv3Exception("Captcha request error.", e);
        }
    }
}

ReCAPTCHAv3Exception.java file:

package logic.controller_captcha.recaptchav3;

public class ReCAPTCHAv3Exception extends Throwable {

    public ReCAPTCHAv3Exception(String message) {
        super( message );
    }

    public ReCAPTCHAv3Exception(String message, Throwable cause) {
        super( message, cause );
    }
}

ReCAPTCHAv3Response.java file:

package logic.controller_captcha.recaptchav3;

import org.codehaus.jackson.annotate.JsonProperty;

public class ReCAPTCHAv3Response {

    @JsonProperty( "success" )
    private boolean success;

    @JsonProperty( "score" )
    private double score;

    @JsonProperty( "action" )
    private String action;

    @JsonProperty( "challenge_ts" )
    private Object timestamp;

    @JsonProperty( "hostname" )
    private String hostname;

    @JsonProperty( "error-codes" )
    private Object errors;

    public boolean getSuccess() {
        return this.success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public double getScore() {
        return this.score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public String getAction() {
        return this.action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public String getHostname() {
        return this.hostname;
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
    }
}

 

Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join