Hướng dẫn sử dụng Google reCAPTCHA trong ứng dụng Web Java
1. reCAPTCHA là gì
CAPTCHA là một công cụ xác thực trên website để đảm bảo rằng website của bạn không bị SPAM bằng một công cụ tự động. Theo truyền thống captcha là một hình ảnh với dòng các chữ khó phân tích bởi một chương trình tự động, người dùng phải nhập lại dòng chữ giống với chữ trên hình ảnh để chứng minh họ không phải là cái máy. CAPTCHA truyền thống có thể đáp ứng được yêu cầu đặt ra tuy nhiên đôi khi khá phiền phức, các dòng chữ CAPTCHA đôi khi rất khó đọc đối với người dùng.
Hình ảnh một CAPTCHA truyền thống:
reCAPTCHA là một dịch vụ CAPTCHA miễn phí giúp website của bạn chống lại SPAM, các đăng ký độc hại, hoặc các hình thức tấn công khác, nơi mà các chương trình tấn công cố gắng che giấu bản thân tạo ra các hành vi giống con người. reCAPTCHA với giao diện đơn giản, có thể dễ dàng thêm vào blog, forum hoặc website của bạn,...
Hình minh họa dưới đây mô tả nguyên tắc hoạt động của reCAPTCHA:
- Trên form nhập dữ liệu, có chứa Google reCAPTCHA.
- Khi người dùng check vào "I'm not a robot", một Ajax request sẽ tự động gửi tới dịch vụ Google reCAPTCHA và nhận được một mã số xác thực nó được lưu trữ trên một Hidden field (g-recaptcha-response) của form. Tất cả những gì người dùng phải làm là check vào nút "I'm not a robot" thay vì phải đọc một dòng chữ khó đọc được tạo ra bởi CAPTCHA truyền thống.
- Người dùng nhấn nút Submit form, Server sẽ xử lý dữ liệu người dùng gửi tới, tại đây chương trình sẽ tạo một request có chứa thông tin mã xác thực ở bước trên để gửi tới dịch vụ Google reCAPTCHA để kiểm chứng lại mã. Dịch vụ Google reCAPTCHA sẽ gửi lại kết quả xác minh.
3. Đăng ký Google reCAPTCHA
Trước hết bạn cần phải đăng ký Google reCAPTCHA
Sau khi đăng ký thành công bạn có Site-Key & Secret-Key
- Site Key: 6LelZAsTAAAAAAv1ADYDnq8AzbmPmbMvjh-xhfgB
- Secret Key: 6LelZAsTAAAAAKa_s6g2yuJzByYlk0FH_6iTkZJC
4. Tạo Nhanh Project để làm ví dụ
- File/New/Other..
Nhập vào:
- Group Id: org.o7planning
- Artifact Id: reCaptchaDemo
- package: org.o7planning.tutorial.recaptcha
Project đã được tạo ra.
Maven tạo ra webapp project có thể thiếu một vài thành phần, bạn cần sửa nó.
Cấu hình web.xml sử dụng WebApp 3.0 thay vì WebApp 2.3 vốn được tự động tạo ra bởi Maven.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
</web-app>
Cấu hình Maven:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.o7planning</groupId>
<artifactId>reCaptchaDemo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>reCaptchaDemo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Servlet Library -->
<!-- http://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- JSON Library -->
<!-- http://mvnrepository.com/artifact/org.glassfish/javax.json -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
<build>
<finalName>reCaptchaDemo</finalName>
<plugins>
<!-- Config: Maven Tomcat Plugin -->
<!-- http://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- Config: contextPath and Port (Default - /reCaptchaDemo : 8080) -->
<!--
<configuration>
<path>/</path>
<port>8899</port>
</configuration>
-->
</plugin>
</plugins>
</build>
</project>
Project của bạn đã không còn thông báo lỗi.
5. Code Project
Đây là hình ảnh Project sau khi hoàn thành:
MyConstants.java
package org.o7planning.tutorial.recaptcha;
public class MyConstants {
public static final String SITE_KEY ="6LelZAsTAAAAAAv1ADYDnq8AzbmPmbMvjh-xhfgB";
public static final String SECRET_KEY ="6LelZAsTAAAAAKa_s6g2yuJzByYlk0FH_6iTkZJC";
}
VerifyUtils.java
package org.o7planning.tutorial.recaptcha;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.net.ssl.HttpsURLConnection;
public class VerifyUtils {
public static final String SITE_VERIFY_URL = //
"https://www.google.com/recaptcha/api/siteverify";
public static boolean verify(String gRecaptchaResponse) {
if (gRecaptchaResponse == null || gRecaptchaResponse.length() == 0) {
return false;
}
try {
URL verifyUrl = new URL(SITE_VERIFY_URL);
// Mở một kết nối (Connection) tới URL trên.
HttpsURLConnection conn = (HttpsURLConnection) verifyUrl.openConnection();
// Thêm các thông tin Header vào Request chuẩn bị gửi tới server.
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent", "Mozilla/5.0");
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
// Dữ liệu sẽ gửi tới Server.
String postParams = "secret=" + MyConstants.SECRET_KEY //
+ "&response=" + gRecaptchaResponse;
// Send Request
conn.setDoOutput(true);
// Lấy Output Stream (Luồng đầu ra) của kết nối tới Server.
// Ghi dữ liệu vào Output Stream, có nghĩa là gửi thông tin đến Server.
OutputStream outStream = conn.getOutputStream();
outStream.write(postParams.getBytes());
outStream.flush();
outStream.close();
// Mã trả lời được trả về từ Server.
int responseCode = conn.getResponseCode();
System.out.println("responseCode=" + responseCode);
// Lấy Input Stream (Luồng đầu vào) của Connection
// để đọc dữ liệu gửi đến từ Server.
InputStream is = conn.getInputStream();
JsonReader jsonReader = Json.createReader(is);
JsonObject jsonObject = jsonReader.readObject();
jsonReader.close();
// ==> {"success": true}
System.out.println("Response: " + jsonObject);
boolean success = jsonObject.getBoolean("success");
return success;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
LoginServlet.java
package org.o7planning.tutorial.recaptcha.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 958900029856081978L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
RequestDispatcher dispatcher =
req.getServletContext().getRequestDispatcher("/WEB-INF/views/loginView.jsp");
dispatcher.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
DoLoginServlet.java
package org.o7planning.tutorial.recaptcha.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.o7planning.tutorial.recaptcha.VerifyUtils;
@WebServlet(urlPatterns = "/doLogin")
public class DoLoginServlet extends HttpServlet {
private static final long serialVersionUID = 958900029856081978L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
boolean valid = true;
String errorString = null;
// Check userName & password
if (!"tom".equals(userName) || !"tom001".equals(password)) {
valid = false;
errorString = "UserName or Password invalid!";
}
if (valid) {
String gRecaptchaResponse = request.getParameter("g-recaptcha-response");
System.out.println("gRecaptchaResponse=" + gRecaptchaResponse);
// Verify CAPTCHA.
valid = VerifyUtils.verify(gRecaptchaResponse);
if (!valid) {
errorString = "Captcha invalid!";
}
}
if (!valid) {
request.setAttribute("errorString", errorString);
RequestDispatcher dispatcher = //
request.getServletContext().getRequestDispatcher("/WEB-INF/views/loginView.jsp");
dispatcher.forward(request, response);
return;
} else {
request.getSession().setAttribute("loginedUser", userName);
// Redirect to /userInfo
response.sendRedirect(request.getContextPath()+"/userInfo");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
UserInfoServlet.java
package org.o7planning.tutorial.recaptcha.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = "/userInfo")
public class UserInfoServlet extends HttpServlet {
private static final long serialVersionUID = 958900029856081978L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) //
throws ServletException, IOException {
if (req.getSession().getAttribute("loginedUser") == null) {
resp.sendRedirect(req.getContextPath() + "/login");
return;
}
RequestDispatcher dispatcher //
= req.getServletContext().getRequestDispatcher("/WEB-INF/views/userInfoView.jsp");
dispatcher.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) //
throws ServletException, IOException {
this.doGet(req, resp);
}
}
Để sử dụng reCAPTCHA trên trang JSP bạn cần khai báo thư viện javascript. Chú ý rằng reCAPTCHA hỗ trợ 40 ngôn ngữ người dùng. Bạn có thể cấu hình cụ thể ngôn ngữ hiển thị trên reCAPTCHA hoặc để mặc định, trong trường hợp mặc định reCAPTCHA sẽ hiển thị ngôn ngữ theo vị trí địa lý của người dùng (Dựa trên địa chỉ IP).
<!-- reCAPTCHA with English language -->
<script src='https://www.google.com/recaptcha/api.js?hl=en'></script>
<!-- reCAPTCHA with Vietnamese language -->
<script src='https://www.google.com/recaptcha/api.js?hl=vi'></script>
<!-- reCAPTCHA with Auto language -->
<script src='https://www.google.com/recaptcha/api.js'></script>
/WEB-INF/views/loginView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
<!-- reCAPTCHA Libary -->
<script src='https://www.google.com/recaptcha/api.js?hl=en'></script>
</head>
<body>
<h3>Login:</h3>
<p style="color:red;">${errorString}</p>
<form name="loginForm" method="POST" action="doLogin">
<table border="0">
<tr>
<td>User Name</td>
<td><input type="text" name="userName" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" /></td>
</tr>
</table>
<!-- reCAPTCHA -->
<div class="g-recaptcha"
data-sitekey="6LelZAsTAAAAAAv1ADYDnq8AzbmPmbMvjh-xhfgB"></div>
<input type="submit" value="Submit" />
</form>
<p style="color:blue;">User Name: tom, Password: tom001</p>
</body>
</html>
/WEB-INF/views/userInfoView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>User Info</title>
</head>
<body>
Hello ${loginedUser}
</body>
</html>
- Tạo Google API Console Project và OAuth2 Client ID
- Đăng ký Google Map API Key
- Kiếm tiền chuyên nghiệp với Ezoic - đối tác của Google
- Hướng dẫn sử dụng Google reCAPTCHA trong ứng dụng Web Java
- Bắt đầu với Google Search Console Java API
- Đánh chỉ mục trang với Java Google Indexing API
- Thao tác với tập tin và thư mục trên Google Drive sử dụng Java
- Tạo một Google Service Account
- Liệt kê, thêm và xoá các Sites với Google Search Java API
- Liệt kê, thêm và xoá các Sitemap với Google Search Java API
Show More
Hướng dẫn lập trình Java Servlet/JSP
- Cài đặt Tomcat Server cho Eclipse
- Cài đặt Glassfish Web Server trên Windows
- Chạy ứng dụng Java web Maven trên Tomcat Maven Plugin
- Chạy ứng dụng Java Web Maven trên Jetty Maven Plugin
- Ví dụ luồng chạy ngầm trong ứng dụng Java Servlet
- Hướng dẫn lập trình Java Servlet cho người mới bắt đầu
- Hướng dẫn và ví dụ Java Servlet Filter
- Hướng dẫn lập trình Java JSP cho người mới bắt đầu
- Hướng dẫn sử dụng Java JSP Standard Tag Library (JSTL)
- Cài đặt Web Tools Platform cho Eclipse
- Tạo một ứng dụng Login đơn giản và bảo mật với Java Servlet Filter
- Tạo một ứng dụng Java Web đơn giản sử dụng Servlet, JSP và JDBC
- Upload và download file lưu trữ trên ổ cứng với Java Servlet
- Upload và Download file từ Database sử dụng Java Servlet
- Hiển thị ảnh từ database với Java Servlet
- Redirect 301 chuyển hướng vĩnh viễn trong Java Servlet
- Làm sao tự động chuyển hướng http thành https trong ứng dụng Java Web
- Hướng dẫn sử dụng Google reCAPTCHA trong ứng dụng Web Java
Show More