如何在 Java Web 应用程序中集成 Google reCAPTCHA
我从来都不喜欢 Captchas,因为最终用户总是需要理解字母并证明自己是人类而不是软件机器人。但最近当我在网站上看到新的Google reCAPTCHA时,我立刻就喜欢上了它。因为我们只需要勾选一个框,它就会判断你是人类还是机器人。谷歌称之为No CAPTCHA reCAPTCHA 体验,它使用高级风险分析引擎和自适应 CAPTCHA 来防止自动化软件在你的网站上进行滥用活动。所以这构成了这篇文章的基础,我将向你展示如何在基于 Java 的 Web 应用程序中使用 Google reCAPTCHA。在我们继续我们的项目之前,你需要做的第一件事是去Google reCAPTCHA并注册。之后,你将获得一个站点密钥,用于在你的网页上显示 reCaptcha 小部件。你还将获得一个密钥,该密钥应保密并用于与 Google 服务器通信以验证验证码响应。在我注册了一个测试站点后,我得到了以下密钥,我将在我的项目中使用它们。请注意,注册时您还需要提供域名,并且密钥只在该域名上有效。此外,密钥将始终在 localhost 上有效,因此我可以轻松地在本地服务器上对其进行测试。现在我们可以转到示例项目。我们将有一个登录页面,用户将在其中输入用户名和密码,除此之外,他还必须解决 reCaptcha 并提交表单。提交表单后,用户名和密码将在我们的应用程序中进行验证,而我们将把带有密钥的验证码响应发送到 Google reCaptcha 服务器并获取响应。来自 Google reCaptcha 的响应是一个带有成功布尔字段的 JSON,如果验证成功,则值为 true,否则为 false。我将使用Java JSON 处理 API来解析响应 JSON。下图展示了我们在 Eclipse 中的最终项目。要获取项目框架,只需在 Eclipse 中创建一个“动态 Web 项目”,然后将其转换为 Maven 项目。只需在pom.xml
JSON API 文件中添加以下依赖项即可。
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.2</version>
</dependency>
让我们逐一研究一下每个组件。
使用 Google reCAPTCHA 查看页面
下面是我们的登录 html 页面代码。login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="US-ASCII">
<title>Login Page</title>
<script src="https://www.google.com/recaptcha/api.js"></script>
</head>
<body>
<form action="LoginServlet" method="post">
Username: <input type="text" name="user"> <br> Password:
<input type="password" name="pwd"> <br>
<div class="g-recaptcha"
data-sitekey="6LdMAgMTAAAAAGYY5PEQeW7b3L3tqACmUcU6alQf"></div>
<br> <input type="submit" value="Login">
</form>
</body>
</html>
我们需要在 HTML 头部添加 Google reCaptcha JS 文件,然后添加<div class="g-recaptcha" data-sitekey="Site-key"></div>
我们的表单以获取 reCaptcha 小部件。这一切都在客户端,真的就这么简单!一旦用户通过验证,他将被发送到下面的成功页面。LoginSuccess.jsp
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Login Success Page</title>
</head>
<body>
<h3>Hi Pankaj, Login successful.</h3>
<a href="login.html">Login Page</a>
</body>
</html>
登录 Servlet
下面是我们简单的 LoginServlet.java servlet 代码,我们在其中验证用户名和密码字段。为简单起见,它们嵌入WebInitParam
在 servlet 代码本身中。请注意,您需要使用 Servlet 3 才能使用这些注释,因此您需要使用支持 servlet spec 3 的 Tomcat-7 或更高版本。
package com.journaldev.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.journaldev.utils.VerifyRecaptcha;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet(description = "Login Servlet", urlPatterns = { "/LoginServlet" }, initParams = {
@WebInitParam(name = "user", value = "Pankaj"),
@WebInitParam(name = "password", value = "journaldev") })
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = -6506682026701304964L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// get request parameters for userID and password
String user = request.getParameter("user");
String pwd = request.getParameter("pwd");
// get reCAPTCHA request param
String gRecaptchaResponse = request
.getParameter("g-recaptcha-response");
System.out.println(gRecaptchaResponse);
boolean verify = VerifyRecaptcha.verify(gRecaptchaResponse);
// get servlet config init params
String userID = getServletConfig().getInitParameter("user");
String password = getServletConfig().getInitParameter("password");
// logging example
System.out.println("User=" + user + "::password=" + pwd + "::Captcha Verify"+verify);
if (userID.equals(user) && password.equals(pwd) && verify) {
response.sendRedirect("LoginSuccess.jsp");
} else {
RequestDispatcher rd = getServletContext().getRequestDispatcher(
"/login.html");
PrintWriter out = response.getWriter();
if (verify) {
out.println("<font color=red>Either user name or password is wrong.</font>");
} else {
out.println("<font color=red>You missed the Captcha.</font>");
}
rd.include(request, response);
}
}
}
一旦提交了带有验证码的表单,我们就会获得需要发送验证的“g-recaptcha-response”请求参数。最后一部分是实用程序类,用于发送 POST 请求进行验证并解析 JSON 响应并相应返回。
package com.journaldev.utils;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.net.ssl.HttpsURLConnection;
public class VerifyRecaptcha {
public static final String url = "https://www.google.com/recaptcha/api/siteverify";
public static final String secret = "6LdMAgMTAAAAAJOAqKgjWe9DUujd2iyTmzjXilM7";
private final static String USER_AGENT = "Mozilla/5.0";
public static boolean verify(String gRecaptchaResponse) throws IOException {
if (gRecaptchaResponse == null || "".equals(gRecaptchaResponse)) {
return false;
}
try{
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
// add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
String postParams = "secret=" + secret + "&response="
+ gRecaptchaResponse;
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + postParams);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
//parse JSON response and return 'success' value
JsonReader jsonReader = Json.createReader(new StringReader(response.toString()));
JsonObject jsonObject = jsonReader.readObject();
jsonReader.close();
return jsonObject.getBoolean("success");
}catch(Exception e){
e.printStackTrace();
return false;
}
}
}
就这些了。我们的应用程序已经准备就绪,下面是我们根据用户输入获得的响应页面。带有 Google Recaptcha 小 部件的登录页面 客户端的 Google Recaptcha 验证服务器端 Google Recaptcha 验证后的响应页面Recaptcha 未解决的响应Recaptcha 已解决但用户/密码不匹配您可以从以下链接下载项目并试用它以了解更多信息。
下载 Google reCAPTCHA Java Web 应用项目