Angular2 Hello World Example | JavaInUse



Use Google reCaptcha with AngularJS



Overview

In a previous chapter we created an AngularJS Application with Partials and ngRoute. We will be using this code to implement the Google reCaptcha. This task we will divide in 3 parts-
Registration of domain for Google Recaptcha.
  • Register the domain with google to get the public and private keys required for implementing the Captcha
Client Side implementation.
  • Display the Google recaptcha on our index.html page.
  • Get the recaptcha value after user selects the recaptcha for submission.
Server Side implementation.
  • Call the google api to verify if the user has correctly selected captcha

Video

This tutorial is explained in the below Youtube Video.

Lets Begin

Our Maven project will be as follows-

a. Registration of domain for Google Recaptcha --
For using the Google Recaptcha we will have to register with google using our domain name. After registration google provides us with public and private keys for authentication. For this got to- https://www.google.com/recaptcha. On registering the domain we get the public and private key required.

b.Client Side implementation -
We use the above keys for displaying the Google reCaptcha in our index.html. For this, download the angular-recaptcha.min.js and include it in the index.html. Add the following URL in the head-
"https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit" async defer.
Add the div tag with vc-recaptcha directive to display the captcha
Along with the vc-recaptcha we have the key which is the public key we get after registering our domain in step 1. It can also be tested locally without the domain name on localhost. So our index.html page will be as follows-
<!DOCTYPE html>
<html ng-app="blog">
<head>
<script src="scripts/angular.min.js"></script>
<script src="scripts/script.js"></script>
<script src="scripts/angular-recaptcha.min.js"></script>
<script
	src="https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit"
	async defer></script>
	
</head>
<body>
	<div>
		<form name="recap.signupForm"
			ng-submit="recap.signup()">
			<div class="form-group">
			<label>Name</label> <input type="text" class="form-control"
				ng-model="recap.name" placeholder="Enter Name" required>
	</div>
	<div class="form-group">
		<label>Password</label> <input type="password" class="form-control"
			ng-model="recap.password" placeholder="Password" required>
	</div>

	<button type="submit" class="btn btn-default">Submit</button>
	<!-- Display recaptcha -->
	
	<div tabindex="3" theme="clean" vc-recaptcha
		key="'6LePCiYTDDDDDKyEwj6RIrqGkDJHJHJtg_G'"></div>
	</form>
	</div>
	</body>
</html>
Now modify the script.js file to add the vcRecaptcha as dependency to the blog module as below.
var app = angular.module('blog', ['vcRecaptcha']);
Next we compile the program using maven command
clean install.
Then deploy on Tomcat using maven command
tomcat:run
Go to http://localhost:8080/angular-spring-module-2/ we can see the captcha as below with message
Localhost is not is the list of supported domains for this site key.

Go to http://127.0.0.1:8080/angular-spring-module-2/ and the captcha can be seen correctly.

Our next task is to get the captcha value once user selects it.
For this we will modify the script.js as follows-

var app = angular.module('blog', ['vcRecaptcha']);

app.controller("recapCtrl", function($scope, vcRecaptchaService) {
	var vm = this;
	//If the recaptcha value is empty alert error else alert the recaptcha resonse
	vm.signup = function() {
		if (vcRecaptchaService.getResponse() === "") { 
			alert("Please resolve the captcha and submit!")
		} else {
			alert(vcRecaptchaService.getResponse());
		}
	}
});

In the index.html add the controller as follows-
<!DOCTYPE html>
<html ng-app="blog">
<head>
<script src="scripts/angular.min.js"></script>
<script src="scripts/angular-route.min.js"></script>
<script src="scripts/script.js"></script>
<script src="scripts/angular-recaptcha.min.js"></script>
<script
	src="https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit"
	async defer></script>
	
</head>
<body>
	<div ng-controller="recapCtrl as recap">
		<form name="recap.signupForm"
			ng-submit="recap.signup()">
			
		<div class="form-group">
			<label>Name</label> <input type="text" class="form-control"
				ng-model="recap.name" placeholder="Enter Name" required>
	</div>
	<div class="form-group">
		<label>Password</label> <input type="password" class="form-control"
			ng-model="recap.password" placeholder="Password" required>
	</div>

	<button type="submit" class="btn btn-default">Submit</button>
	<!-- Display recaptcha -->
	
	<div tabindex="3" theme="clean" vc-recaptcha
		key="'6LeLiiYTAAAAAKyEhMTrEbONL4uE7juytegjk_G'"></div>
	</form>
	</div>
	</body>
</html>
Now on selecting the captcha and clicking on submit we get the recaptcha response in the alert successfully.

c.Server Side implementation -
Now that we get the Google Recaptcha response correctly our next step would be to verify if the user has selected correctly the captcha by calling the google verify API. The google verify API is as follows-

So we have the secret key, that we got in step a above. The google recaptcha response we got in step c, when the user selects the captcha. The third parameter hostname is optional and we are not going to use it. After calling the verify API with these parameters if it is successull we get the response as follows.

The direct GET call using verify api can be done from the script.js. I found it much simpler to write a GET call from a Java class exposed as a webservice. So from the script.js we call the POST api along with Recpatcha API to the java class. From this class we call the Google verify API.

For this have added additional pom dependencies for Spring and JSON parsing. The details you can get from the source code attached. Here i will only explain some part.

For script.js added a webservice call to url /angular-hashbang/verifyUser.do. For this we have to add the angular-resource.min.js script.
var app = angular.module('blog', [ 'vcRecaptcha', 'ngResource' ]);

app.factory('sessionService', function($resource) {
	var service = {};
	var a;
	service.register = function(recaptcha) {
		var Register = $resource("/angular-hashbang/verifyUser.do");
		Register.save({}, recaptcha, a);
	};
	return service;
});

app.controller("recapCtrl",
		function($scope, vcRecaptchaService, sessionService) {
			var vm = this;
			vm.signup = function() {
				if (vcRecaptchaService.getResponse() === "") { // if string is
																// empty
					alert("Please resolve the captcha and submit!")
				} else {
					alert(vcRecaptchaService.getResponse());
					sessionService.register(vcRecaptchaService.getResponse())
				}
			}
		});

So write Java class exposed as Webservice using Spring Rest. First we will define the domain class which will be used to parse reponse from JSON.
package com.javainuse.domain;

import com.fasterxml.jackson.annotation.JsonProperty;

public class Response {

	private boolean success;
	private String challenge_ts;
	private String hostName;

	@JsonProperty("success")
	public boolean isSuccess() {
		return success;
	}

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

	@JsonProperty("challenge_ts")
	public String getChallenge_ts() {
		return challenge_ts;
	}

	public void setChallenge_ts(String challenge_ts) {
		this.challenge_ts = challenge_ts;
	}

	@JsonProperty("hostname")
	public String getHostName() {
		return hostName;
	}

	public void setHostName(String hostName) {
		this.hostName = hostName;
	}
}
Next we define the REST API as follows. Notice here that we make use of the secret Recaptcha key below.
package com.javainuse.controller;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import com.javainuse.domain.Response;

@Controller
public class RecaptchaManagementController {

	//call the recpatcha url for verification.
	public static final String url = "https://www.google.com/recaptcha/api/siteverify";
	public static final String secret = "6LeQCiYTbbbDDD1xK2-U4cAaBCDoENFhTRDKyy79god";

	@RequestMapping(value = "/verifyUser.do", method = RequestMethod.POST, consumes = {
			MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
	@ResponseBody
	public boolean viewAllItems(@RequestBody String gRecaptchaResponse) {
		System.out.println(gRecaptchaResponse);
		if (gRecaptchaResponse == null || "".equals(gRecaptchaResponse)) {
			return false;
		}
		try {

			RestTemplate restTemplate = new RestTemplate();
			HttpHeaders headers = new HttpHeaders();
			headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);

			UriComponentsBuilder builder = UriComponentsBuilder
					.fromHttpUrl(url).queryParam("secret", secret)
					.queryParam("response", gRecaptchaResponse);
			HttpEntity<String> entity = new HttpEntity<>(headers);

			ResponseEntity<Response> response = restTemplate.exchange(builder
					.build().encode().toUri(), HttpMethod.GET, entity,
					Response.class);

			Response rs = response.getBody();
			System.out.println(rs.isSuccess());

			if (response.getStatusCode().equals("200")) {
				return rs.isSuccess();
			}

			return false;

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

	}
}
Now build and deploy the application using maven:tomcat run command and after selecting the captcha click submit- we get the output as-

Download Source Code

Download it - Google Recaptcha with AngularJS

 

See Also

Creating a Simple AngularJS Application with ngRoute and Partials Removing the # from the AngularJS URL Use AngularJS NgCloak directives Example PrimeNG-UI Components for AngularJS 2 Basic Example