Java WebアプリケーションにGoogle reCAPTCHAを統合する方法

私は元々、キャプチャを好きではありませんでした。なぜなら、利用者には文字を理解し、自分が人間であることを証明しなければならないという負担があったからです。しかし最近、ウェブサイトで新しいGoogle reCAPTCHAを見たときは、すぐに気に入りました。なぜなら、チェックボックスをクリックするだけで、あなたが人間かロボットかを判断してくれるからです。GoogleはそれをNo CAPTCHA reCAPTCHA体験と呼び、進化したリスク分析エンジンと適応型CAPTCHAを使って、自動ソフトウェアによる悪意のある活動を抑制しています。それが今回の投稿の基盤となり、JavaベースのウェブアプリケーションでGoogle reCAPTCHAをどのように利用するかを紹介します。プロジェクトを進める前に、まずGoogle reCAPTCHAにアクセスしてサインアップする必要があります。その後、ウェブページにreCAPTCHAウィジェットを表示するために使用されるサイトキーを取得します。また、キャプチャの応答を確認するために、秘密キーも取得します。テストサイトを登録した後、以下のキーを取得し、プロジェクトで利用します。サインアップ時にはドメイン名を提供する必要があり、キーはそのドメイン名のみで機能します。また、キーは常にローカルホストで機能するため、自分のローカルサーバーで簡単にテストできます。これで準備が整ったので、次に例題のプロジェクトに移りましょう。ログインページがあり、利用者はユーザー名とパスワードを入力するだけでなく、reCaptchaも解かなければなりません。フォームが送信されると、ユーザー名とパスワードはアプリケーションで検証され、キャプチャの応答は秘密キーと一緒にGoogle reCAPTCHAサーバーに送信され、応答を受け取ります。Google reCAPTCHAからの応答は、成功の真偽値を持つJSONです。検証が成功すると、値はtrueになり、それ以外の場合はfalseになります。私はJava JSON処理APIを使用して応答JSONを解析します。以下の画像は、Eclipseでの最終的なプロジェクトを示しています。プロジェクトの土台を得るためには、Eclipseで「動的Webプロジェクト」を作成し、それをMavenプロジェクトに変換するだけです。JSON APIのためのpom.xmlファイルに以下の依存関係を追加します。

<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ファイルを追加し、

内に

を追加することで、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>

ログインサーブレット

以下は私たちのシンプルなLoginServlet.javaサーブレットコードです。このコードでは、ユーザー名とパスワードのフィールドを検証しています。簡単のために、これらのフィールドはサーブレットコード自体にWebInitParamとして埋め込まれています。これらの注釈を使用するにはServlet 3を使用する必要があるため、Tomcat-7または後のバージョンを使用する必要があります。

package com.scdev.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.scdev.utils.VerifyRecaptcha;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet(description = "Login Servlet", urlPatterns = { "/LoginServlet" }, initParams = {
		@WebInitParam(name = "user", value = "Pankaj"),
		@WebInitParam(name = "password", value = "scdev") })
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.scdev.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ウェブアプリプロジェクトをダウンロードしてください。

コメントを残す 0

Your email address will not be published. Required fields are marked *