如何在 Java Web 应用程序中集成 Google reCAPTCHA

I never liked Captchas because the burden was always on end user to understand the letters and prove that he is a human and not a software bot. But when I recently saw new Google reCAPTCHA on a website, I instantly liked it. Because all we need is to check a box and it will figure out if you are a human or robot. Google is calling it No CAPTCHA reCAPTCHA experience and it uses an advanced risk analysis engine and adaptive CAPTCHAs to keep automated software from engaging in abusive activities on your site. google recaptcha So that formed the basis of this post where I will show you how to utilize Google reCAPTCHA in your java based web application. Before we move on with our project, first thing you need to do is go to Google reCAPTCHA and sign up. After that you will get a Site key that is used to display the reCaptcha widget on your web pages. You will also get a Secret key that should be kept secret and used in communicating with Google server to verify the captcha response. After I registered a test site, I got below keys and I will utilize them in my project. Note that while signup you also need to provide domain name and the keys will work only on that domain name. Also keys will always work on localhost, so I can easily test it on my local server. Google reCAPTCHA keys Now we can head over to our example project. We will have a login page where user will enter username and password, apart from that he will also have to solve reCaptcha and submit the form. Once the form is submitted, username and password will be validated in our application, whereas we will send the captcha response with secret key to Google reCaptcha server and get the response. The response from Google reCaptcha is a JSON with a success boolean field, if validated success value will be true otherwise it will be false. I will use Java JSON Processing API to parse the response JSON. Below image shows our final project in Eclipse. Google reCAPTCHA Java Web Application To get the project skeleton, just create a "Dynamic Web Project" in Eclipse and then convert it to Maven project. Just add below dependency in pom.xml file for JSON API.

1<dependency>
2    <groupId>org.glassfish</groupId>
3    <artifactId>javax.json</artifactId>
4    <version>1.0.2</version>
5</dependency>

让我们看看每个组件一个接一个。

使用 Google reCAPTCHA 查看页面

下面是我们的登录HTML页面代码:login.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<meta charset="US-ASCII">
 5<title>Login Page</title>
 6<script src="https://www.google.com/recaptcha/api.js"></script>
 7</head>
 8<body>
 9
10    <form action="LoginServlet" method="post">
11
12    	Username: <input type="text" name="user"> <br> Password:
13    	<input type="password" name="pwd"> <br>
14    	<div class="g-recaptcha"
15    		data-sitekey="6LdMAgMTAAAAAGYY5PEQeW7b3L3tqACmUcU6alQf"></div>
16    	<br> <input type="submit" value="Login">
17    </form>
18</body>
19</html>

我们需要在 HTML 标题中添加 Google reCaptcha JS 文件,然后在我们的表单中添加 <div class="g-recaptcha" data-sitekey="Site-key"></div> 以获得 reCaptcha 视图。

 1<%@ page language="java" contentType="text/html; charset=US-ASCII"
 2    pageEncoding="US-ASCII"%>
 3<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
 4<html>
 5<head>
 6<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
 7<title>Login Success Page</title>
 8</head>
 9<body>
10<h3>Hi Pankaj, Login successful.</h3>
11<a href="login.html">Login Page</a>
12</body>
13</html>

登录服务器

下面是我们简单的 LoginServlet.java servlet 代码,我们正在验证用户名和密码字段. 为了方便,它们被嵌入为WebInitParam在 servlet 代码本身。 请注意,您需要使用 Servlet 3 来使用这些注释,因此您需要使用支持 servlet spec 3 的 Tomcat-7 或更高版本。

 1package com.journaldev.servlet;
 2
 3import java.io.IOException;
 4import java.io.PrintWriter;
 5
 6import javax.servlet.RequestDispatcher;
 7import javax.servlet.ServletException;
 8import javax.servlet.annotation.WebInitParam;
 9import javax.servlet.annotation.WebServlet;
10import javax.servlet.http.HttpServlet;
11import javax.servlet.http.HttpServletRequest;
12import javax.servlet.http.HttpServletResponse;
13
14import com.journaldev.utils.VerifyRecaptcha;
15
16/**
17 * Servlet implementation class LoginServlet
18 */
19@WebServlet(description = "Login Servlet", urlPatterns = { "/LoginServlet" }, initParams = {
20    	@WebInitParam(name = "user", value = "Pankaj"),
21    	@WebInitParam(name = "password", value = "journaldev") })
22public class LoginServlet extends HttpServlet {
23
24    private static final long serialVersionUID = -6506682026701304964L;
25
26    protected void doPost(HttpServletRequest request,
27    		HttpServletResponse response) throws ServletException, IOException {
28
29    	// get request parameters for userID and password
30    	String user = request.getParameter("user");
31    	String pwd = request.getParameter("pwd");
32    	// get reCAPTCHA request param
33    	String gRecaptchaResponse = request
34    			.getParameter("g-recaptcha-response");
35    	System.out.println(gRecaptchaResponse);
36    	boolean verify = VerifyRecaptcha.verify(gRecaptchaResponse);
37
38    	// get servlet config init params
39    	String userID = getServletConfig().getInitParameter("user");
40    	String password = getServletConfig().getInitParameter("password");
41    	// logging example
42    	System.out.println("User=" + user + "::password=" + pwd + "::Captcha Verify"+verify);
43
44    	if (userID.equals(user) && password.equals(pwd) && verify) {
45    		response.sendRedirect("LoginSuccess.jsp");
46    	} else {
47    		RequestDispatcher rd = getServletContext().getRequestDispatcher(
48    				"/login.html");
49    		PrintWriter out = response.getWriter();
50    		if (verify) {
51    			out.println("<font color=red>Either user name or password is wrong.</font>");
52    		} else {
53    			out.println("<font color=red>You missed the Captcha.</font>");
54    		}
55    		rd.include(request, response);
56    	}
57    }
58}

一旦带有captcha的表单被提交,我们就会得到g-recaptcha-response请求参数,需要发送以进行验证。最后一部分是发送POST请求以进行验证的实用类,并对JSON响应进行解析并相应返回。

 1package com.journaldev.utils;
 2
 3import java.io.BufferedReader;
 4import java.io.DataOutputStream;
 5import java.io.IOException;
 6import java.io.InputStreamReader;
 7import java.io.StringReader;
 8import java.net.URL;
 9
10import javax.json.Json;
11import javax.json.JsonObject;
12import javax.json.JsonReader;
13import javax.net.ssl.HttpsURLConnection;
14
15public class VerifyRecaptcha {
16
17    public static final String url = "https://www.google.com/recaptcha/api/siteverify";
18    public static final String secret = "6LdMAgMTAAAAAJOAqKgjWe9DUujd2iyTmzjXilM7";
19    private final static String USER_AGENT = "Mozilla/5.0";
20
21    public static boolean verify(String gRecaptchaResponse) throws IOException {
22    	if (gRecaptchaResponse == null || "".equals(gRecaptchaResponse)) {
23    		return false;
24    	}
25    	
26    	try{
27    	URL obj = new URL(url);
28    	HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
29
30    	// add reuqest header
31    	con.setRequestMethod("POST");
32    	con.setRequestProperty("User-Agent", USER_AGENT);
33    	con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
34
35    	String postParams = "secret=" + secret + "&response="
36    			+ gRecaptchaResponse;
37
38    	// Send post request
39    	con.setDoOutput(true);
40    	DataOutputStream wr = new DataOutputStream(con.getOutputStream());
41    	wr.writeBytes(postParams);
42    	wr.flush();
43    	wr.close();
44
45    	int responseCode = con.getResponseCode();
46    	System.out.println("\nSending 'POST' request to URL : " + url);
47    	System.out.println("Post parameters : " + postParams);
48    	System.out.println("Response Code : " + responseCode);
49
50    	BufferedReader in = new BufferedReader(new InputStreamReader(
51    			con.getInputStream()));
52    	String inputLine;
53    	StringBuffer response = new StringBuffer();
54
55    	while ((inputLine = in.readLine()) != null) {
56    		response.append(inputLine);
57    	}
58    	in.close();
59
60    	// print result
61    	System.out.println(response.toString());
62    	
63    	//parse JSON response and return 'success' value
64    	JsonReader jsonReader = Json.createReader(new StringReader(response.toString()));
65    	JsonObject jsonObject = jsonReader.readObject();
66    	jsonReader.close();
67    	
68    	return jsonObject.getBoolean("success");
69    	}catch(Exception e){
70    		e.printStackTrace();
71    		return false;
72    	}
73    }
74}

That's all. Our application is ready, below are the response pages we get based on user inputs. Login Page with Google Recaptcha Widget Google Recaptcha Widget Google Recaptcha Validated at client side Google Recaptcha Validated Response page after server side Google Recaptcha Validation Google Recaptcha Server Validated Response where Recaptcha was not solved Google Recaptcha Java Not Solved Recaptcha Solved but user/password didn't match java captcha Other validation error You can download the project from below link and play around with it to learn more.

(下载Google reCAPTCHA Java Web App Project)

Published At
Categories with 技术
Tagged with
comments powered by Disqus