Google recaptcha com java

O captcha, que significa Completely Automated Public Turing test to tell Computers and Humans Apart” (teste de Turing público completamente automatizado para diferenciar computadores e humanos), é um teste de segurança bastante conhecido por quem costuma utilizar a internet, e passou também a ser odiado pelas suas letras distorcidas e difíceis de decifrar. O conceito do captcha, que é basicamente uma imagem com letras e números distorcidos que só poderiam ser identificados por humanos, foi reformulada por pesquisadores da universidade de Carnegie Mellon, que passaram a aproveitar esse ato de digitar letras distorcidas para ajudar a digitalizar livros. Assim, ao invés de digitar um texto distorcido, você passaria a digitar dois textos distorcidos, sendo um o teste captcha e o outro sua contribuição inconsciente para a digitalização de livros antigos. Esse é o recaptcha.

Em 2013 o google inovou (pra variar) mudando completamente o formato do captcha/recaptcha criando o “No captcha recaptcha”, ou seja, um recaptcha que substitui as letras distorcidas por uma simples janelinha perguntando se você é um robô. Parece ineficiente, mas, segundo o google, existe um algoritmo bastante sofisticada por traz dessa janelinha que consegue detectar se quem está clicando é um humano ou robô pela forma como ele interage com a tela.

Nesse post vou montar um exemplo bem simples para incluir o No captcha recaptcha em uma aplicação web java:

 1 – O primeiro passo é criar uma chave para sua aplicação web, no site do google recaptcha. Será gerado para você uma chave pública (site key) e uma chave secreta (secret key). Para servidor local (localhost), qualquer chave é considerada válida, mas precisa ser gerada pelo site do google recaptcha.

2 – No formulário de validação do seu site, inclua o trecho:

<div class="g-recaptcha" data-sitekey="<sua chave pública>"></div>

dentro do formulário, como no exemplo:

<html>
  <head>
    <title>reCAPTCHA demo: Simple page</title>
     <script src="https://www.google.com/recaptcha/api.js" async defer></script>
  </head>
  <body>
    <form action="hello" method="POST">
      <div class="g-recaptcha" data-sitekey="<sua chave pública>"></div>
      <br/>
      <input type="submit" value="Submit">
    </form>
  </body>
</html>

Esse simples div já carregará a janela de verificação do google recaptcha, conforme Figura 1:

recaptcha
Figura 1 – Google recaptcha

 

3 – No servlet que receberá os dados de seu formulário, será necessário fazer uma requisição para o site do google passando a resposta obtida pelo formulário, a chave secreta e o ip da requisição. Para deixar o código mais legível, criei uma classe separada para essa tarefa. A classe ficou assim:

public class RecaptchaService {

	public boolean checkRecaptcha(HttpServletRequest request){
		String recap = request.getParameter("g-recaptcha-response");

		try{
			String urlGoogle = "https://www.google.com/recaptcha/api/siteverify?secret=%s&response=%s&remoteip=%s";
			String secret = "<sua chave secreta>";
			// Send get request to Google reCaptcha server with secret key
			String urlFormatada = String.format(urlGoogle, secret, recap,
					(request.getRemoteAddr() != null ? request.getRemoteAddr() : "0.0.0.0"));
			URL url = new URL(urlFormatada);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			String line, outputString = "";
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			while ((line = reader.readLine()) != null) {
				outputString += line;
			}
			// Convert response into Object
			CaptchaResponse capRes = new Gson().fromJson(outputString, CaptchaResponse.class);

			// Verify whether the input from Human or Robot
			if (capRes.isSuccess()) {
				// Input by Human
				return true;
			} else {
				// Input by Robot
				return false;
			}

		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}
 	private class CaptchaResponse {
		private boolean success;
 		private String[] errorCodes;

 		public boolean isSuccess() {
 			return success;
 		}

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

 		public String[] getErrorCodes() {
 			return errorCodes;
 		}

	 	public void setErrorCodes(String[] errorCodes) {
 			this.errorCodes = errorCodes;
 		}

 	}	

Nessa classe estou fazendo uma requisição “GET” para o site “https://www.google.com/recaptcha/api/siteverify” passando a resposta do recaptcha vinda do formulário(“g-recaptcha-response”), a chave secreta e o ip da requisiçao, que é opcional. A url está sendo montada na linha 10. É recomendável fazer uma requisição “POST” ao invés de “GET”. Utilizei GET apenas para simplificar o exemplo. O site de verificação do google retornará uma resposta json, ou seja, uma string com um formato padronizado. Para simplificar, utilizei a api Gson, também do google, para transformar a resposta em um objeto do tipo CatpchaResponse (linhas 37 a 57). A resposta original fica nesse formato: 

{
  "success": true|false,
  "error-codes": [...]   // optional
}

4 – Agora, baseado na análise do google, é só exibir a resposta para o usuário:

public class RecaptchaServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		RecaptchaService service = new RecaptchaService();
		boolean isHuman = service.checkRecaptcha(req);
		
		if (isHuman){
			req.setAttribute("resposta", "Parabéns, você é humano!");
		}else{
			req.setAttribute("resposta", "Você não é humano!");
		}
			
		
		RequestDispatcher rd = req.getRequestDispatcher("hello.jsp");
		rd.forward(req, resp);
	}
}
hellorecaptcha
Figura 2 – Resposta para a validação

Esse foi um exemplo bem simples para ilustrar o uso do google recaptcha. É possível personalizar a exibição da janela do recaptcha como um componente javascript normal. Mais detalhes podem ser obtidos no site da documentação do google recaptcha.

 

Por MARCIA TANIMOTO

Formada em Informática - UEM/Maringá. Analista de Sistemas, apaixonada pela profissão, curiosa e MATERANA de coração.

Postado em: 28 de setembro de 2015

Confira outros artigos do nosso blog

REST não é JSON

21 de agosto de 2017

Bruno Sofiato

[Webinar] Profile de aplicações Java com Oracle Mission Control e Flight Recorder

24 de julho de 2017

Danival Calegari

Criando Mocks de serviços REST com SoapUI

27 de junho de 2017

Monise Costa

JavaScript 6: diferença entre var, let e const

09 de maio de 2017

Otávio Felipe do Prado

Deixe seu comentário