ウェブサイトにキャプチャを導入する方法【reCAPTCHAの使い方】

ウェブサイトにキャプチャを導入する方法【reCAPTCHAの使い方】

WEBサイトのコメントシステムやお問い合わせフォームにおいて、ロボットによるスパム投稿を排除するための機能、CAPTCHA(キャプチャ)を実装する方法を解説します。今回はGoogleが提供する「reCAPTCHA」を利用しましょう。

reCAPTCHAとは?

「reCAPTCHA」はGoogleが提供するキャプチャ・システムで、従来のように判別困難な文字を入力する作業ではなく、画像を選択するだけで、人間とロボットの判定を実現します。ただ、2014年12月4日現在、画像を選択するだけの簡易キャプチャ機能は特定のサイトのみで反映されており、順次、他のウェブサイトにも適用していくとのことです。このサンプルのキャプチャは、まだ従来のタイプです。話をまとめると、この記事で紹介する方法でキャプチャを設置しておけば、そのうち、機能が自動で更新されるということですね。

サンプルデモ

このサンプルは、キャプチャによる認証をクリアすると、フォームのロックが解除され、入力できるようにしたものです。なお、サンプルなので、「送信」をクリックしても何も起こりません。もう一度試す場合は、大変お手数ですが、リロードをして下さい。

名前を入力して下さい。

準備(APIキーの取得)

reCAPTCHAを利用するための準備を行ないます。

必要なもの

reCAPTCHAを利用するために必要なものは下記2点です。Googleのユーザーアカウントをまだ持っていない人は、作成して下さい。

Googleのユーザーアカウント
普段、Googleユーザーとして利用しているアカウントです。
ウェブサイトのURLアドレス
キャプチャを実装するウェブサイトのURLアドレスです。

reCAPTCHAへのアクセス

それでは、ウェブサイトを登録してreCAPTCHAのライブラリを入手しましょう。Googleにあらかじめログインしてから、下記のページにアクセスして下さい。

ウェブサイトの登録

「Create an API Key」をクリックする
「Create an API Key」をクリックする

reCAPTCHAのページにアクセスしたら、左側のメニューにある「Create an API Key」というリンクテキストをクリックして下さい。

許可するドメインを入力する
許可するドメインを入力する

登録フォームが表示されます。上から「Label」「Domains」「Owners」の順に入力します。「Label」は、このキャプチャを識別するための名前を決めます。複数のreCAPTCHAを作成する時などに見分けるための管理上の名称です。「Domains」は、このキャプチャが動作するドメインを指定します。このサイトの場合、syncer.jpとなります。「Owners」には、あなたのGoogleアカウントのメールアドレスを入力して下さい。なお、ここの設定を変更したり追加したりする場合、30分ほど反映が遅れる場合があるとのことです。

このキャプチャはアクセス解析ができます。その際に、このプログラムが自動的に抽出したスパムの存在をレポートするには、「Get alerts about this site」にチェックを入れて下さい。準備ができたら「Register」をクリックしましょう。

「Adding reCAPTCHA to your site」の項目
「Adding reCAPTCHA to your site」の項目

入力に問題がなければ、あなたのウェブサイト用のキャプチャが作成されます。これは作成後、画面遷移したキャプチャの管理画面です。一番上の「Analytics」には、このキャプチャが利用された履歴や、スパムの検出などの分析データが掲載されています。一番下の「Key Settings」では、このキャプチャの設定を変更したり、削除することができます。さて、赤枠の部分(「Adding reCAPTCHA to your site」の項目)を見て下さい。

「Site key」「Secret key」を確認する
「Site key」「Secret key」を確認する

上部の「Keys」の項目にある「Site key」「Secret key」がプログラムの利用に必要なコードです。前者の「Site Key」はHTMLソース上に記載するものなので、他人に知られても問題はありませんが、後者の「Secret Key」は知られないように気を付けて下さい。

HTMLへの実装

準備ができたら、reCAPTCHAを実装していきましょう。まずはHTML部分です。

ライブラリの読み込み

まずはライブラリ(JavaScript)をHTMLのヘッダー内などで読み込んでおきましょう。Googleのサーバー内にあるので、https://から指定します。

https://www.google.com/recaptcha/api.js リンク

HTML

<head>
	<script src="https://www.google.com/recaptcha/api.js"></script>
</head>

言語の指定

通常、ライブラリはキャプチャの案内文などの言語を自動で決定しますが、それを明示的に指定することができます。それには、ライブラリを読み込む際に、hlプロパティに、国コードを付けて下さい。下記は英語にするサンプルです。

https://www.google.com/recaptcha/api.js?hl=en

キャプチャの挿入

続いてreCAPTCHAの機能が付いたフォームを作成してみましょう。仕上げにキャプチャを挿入します。それには、<form>〜</form>の間のどこかに、下記のコードを挿入するだけです。クラス属性値にg-recaptchadata-sitekey属性値に、取得した「Site key」をセットして下さい。

HTML

<div class="g-recaptcha" data-sitekey="{あなたのSite key}"></div>

次がreCAPTCHAのコードを挿入したフォームの例です。

HTML

<form method="GET">
	<div class="g-recaptcha" data-sitekey="{あなたのSite key}"></div>
	<p><label>名前</label></p>
	<p><input type="text" name="text-01"></p>
	<p><input type="submit" value="送信"></p>
</form>

ちなみに、タグ名はdivでなくても、大丈夫です。

HTML

<p class="g-recaptcha" data-sitekey="{あなたのSite key}"></p>

このコードの動作を確認する

パラメータ

g-recaptchaのクラス属性値を指定したdiv要素に、下記の属性値を付けて、reCAPTCHAをデザインすることができます。

data-sitekey
取得したAPIキーのうち、Site Keyの方を指定する。
data-theme
reCAPTCHAのデザインを指定する。デフォルトはlight
dark … ダーク。黒背景のスタイル。
light … ライト。
data-type
認識のタイプ。reCAPTCHAは通常、チェックマークを付けるだけの作業ですが、判定によっては画像を見ての文字入力、または音声を聴いての文字入力が求められます。これらはユーザーが切替可能ですが、「どちらを先に表示するか」をdata-type属性値で指定することができます。デフォルトはimage
image … 指定された画像をクリックする。
audio … 音声を聴いて、文字を入力する。
data-size
reCAPTCHAのサイズ。デフォルトはnormalです。
normal … ノーマル。
compact … コンパクト。通常よりも小さいサイズ。
data-tabindex
tabindex(タブ移動の優先順位)を指定する。デフォルトは0
data-callback
認証クリア後に起動する、JavaScriptの関数名を指定する。
expired-callback
reCAPTCHAは認証クリア後、数分すると有効期限が切れて認証が無効になります。その時に起動したいJavaScriptの関数があったら、その関数名を指定する。

パラメータの指定例

例えば、reCAPTCHAのデザインをダークにしたい場合は、次の通り、HTMLを記述します。パラメータの順序は自由です。

HTML

<div class="g-recaptcha" data-theme="dark" data-sitekey="{あなたのSite key}"></div>

認証システムの実装

認証の仕組み

キャプチャを設置するだけでは意味がありません。「ユーザーがキャプチャによる認証をパスした」ことを、プログラム側に伝えるシステムが必要です。それを実装するためには、仕組みを理解しておきましょう。ユーザーが、キャプチャによる認証をパスすると、下記のようなコードが生成されます。このコードは約2分間のみ有効なものです。

03AHJ_Vuu6KcsH4jclU1-wE4S16thsKXkZO8R7AnEuLlRBYU7TtrNS770vZuGifKdRsILiU-NHXJKuS6pGRZaxqHjDocUstdf8V81EA-jyKHvKloj1wX7ubbB2EsDkGPSJLzDwnp7k9jOzVF_WTPlHVc_JkOnMHJNTeS7TLxPATFHweIatg8VbSvXqLUm4JKF-hb4N1uB5x2WRR9baCkC84jdaSCxUfMhogv6e ... 0cZBbwtUitSQBuQarzcLx0poA6Oq9DXlgc4AQSo0GUVTkup4QQ

その後、ユーザーがフォームのボタンをクリックして、コメントなりメールなりの送信を実行した時、プログラム側に送られる従来のパラメータに、g-recaptcha-responseというパラメータが追加され、その値が上記のコードになります。

フォームから送信されるデータ

例えば、通常のform要素から送信した場合、例えば、送信される内容は下記の通りです。

name=あらゆ&text=こんにちは

これが、キャプチャが実装されていて、さらにユーザーがreCaptchaの認証を経た場合は、パラメータが追加されます。

name=あらゆ&text=こんにちは&g-recaptcha-response=03AHJ_Vuu6KcsH4jclU1-wE4S16thsKXkZO8R7AnEuLlRBYU7TtrNS ...

ユーザーが認証を経ずに送信ボタンを押した場合は、値が空になります。

name=あらゆ&text=こんにちは&g-recaptcha-response=

コードの受け取り

開発者は、プログラム側において、g-recaptcha-responseにある値を受け取り、次の処理に進むことになります。g-recaptcha-responseが空の場合は、ユーザーが認証をしていないことになります。例えばPHPを用いて、フォームからデータを受け取る時は、下記のようになります。ブラウザに出力する意味はありませんが、例えばの場合です。

GETメソッドの場合

$_GET["g-recaptcha-response"]

POSTメソッドの場合

$_POST["g-recaptcha-response"]

コードが正しいものか判定

さて、このコードを受け取ったところで、まだ何の認証にもなってないことは分かると思います。例えば、適当にg-recaptcha-responseというパラメータに値を設定してリクエストが送られる可能性があります。この値が本当に、ユーザーがreCAPTCHAによるキャプチャ認証を通して発行したものかどうかを確認する必要がありますね。そのためには、APIを利用します。下記のURLにリクエストを送って、返り値を解析して下さい。ここで、「Secret key」が登場しますね。

GET https://www.google.com/recaptcha/api/siteverify?secret={Secret key}&response={認証コード}

リクエストが正常に行なわれた時、JSONデータを取得することができます。まず、認証コードが正当なものだと判定された場合のサンプルです。successプロパティがBoolean値のtrueならキャプチャ認証は正当です。

JSON

{
"success": true
}

続いては、ユーザーが認証コードg-recaptcha-responseに適当な値を設定してリクエストしてきたなどして、認証コードが不正だった場合です。successプロパティはBoolean値のfalse、そしてerror-codesプロパティに、不正と判定された原因を示すコードが配列形式で格納されています。単純に判定結果のJSONを出力します。

JSON

{"success": false,"error-codes": ["invalid-input-response"]}

サンプルプログラム

reCAPTCHAを実装したフォームから送られてきたデータを処理する前に、認証コードが正しいか不正かを判定するサンプルプログラムは下記の通りです。

PHP

<?php

	// エラー判定
	if( !isset( $_GET['g-recaptcha-response'] ) )
	{
		$_GET['g-recaptcha-response'] = '' ;
	}

	// シークレットキー
	$secret_key = '' ;

	// エンドポイント
	$endpoint = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $secret_key . '&response=' . $_GET['g-recaptcha-response'] ;

	// 判定結果の取得
	$curl = curl_init() ;
	curl_setopt( $curl , CURLOPT_URL , $endpoint ) ;
	curl_setopt( $curl , CURLOPT_SSL_VERIFYPEER , false ) ;		// 証明書の検証を行わない
	curl_setopt( $curl , CURLOPT_RETURNTRANSFER , true ) ;		// curl_execの結果を文字列で返す
	curl_setopt( $curl , CURLOPT_TIMEOUT , 5 ) ;		// タイムアウトの秒数
	$json = curl_exec( $curl ) ;
	curl_close( $curl ) ;

	// JSONの出力を明示
	header( 'Content-Type: application/json; charset=utf-8' ) ;

	// 結果の出力
	echo $json ;

サンプルデモを見る

コールバックによる処理

JavaScriptの利用

フォームにreCAPTCHAを実装し、そして、フォームから受け取ったデータをプログラム側が処理するところまでは理解していただけたと思います。この章では、この記事冒頭のサンプルのように、送信ボタンをクリックする前の、キャプチャによる認証作業を終えたタイミングでJavaScriptを実行する方法を紹介します。

コールバック関数名の指定

それには、キャプチャを終えたタイミングで実行する関数を指定する必要があります。これは、data-callback属性でその名前を指定できましたね。ここではsyncerRecaptchaCallback()という関数名を指定します。

HTML

<div class="g-recaptcha" data-callback="syncerRecaptchaCallback" data-sitekey="{あなたのSite key}"></div>

フォームの作成

キャプチャ作業を終了したタイミングでフォームを操作できるようにしてみましょう。まずはdisabled属性を使って、各入力要素を操作不能にしておきます。このフォームにはsyncer-recaptcha-formというID属性値を設定しておきます。

HTML

<form method="GET" id="syncer-recaptcha-form">
	<div data-callback="syncerRecaptchaCallback" data-sitekey="{あなたのSite key}" class="g-recaptcha"></div>
	<p><input type="text" name="text-01" disabled></p>
	<p>
		<input type="radio" name="text" name="radio-01" disabled>選択肢1
		<br/><input type="radio" name="text" name="radio-01" disabled>選択肢2
		<br/><input type="radio" name="text" name="radio-01" disabled>選択肢3
	</p>
	<p><button disabled>送信する</button></p>
</form>

JavaScriptの作成

続いて、キャプチャ作業を終えたタイミングで実行するJavaScriptの関数(syncerRecaptchaCallback())を作成しましょう。コールバックに指定した関数が実行される時、認証コードが引数で渡されます。それをcodeという変数で受け取ります。

ここでは単純に、codeが空じゃなければ、フォームの操作不能状態を解除するというプログラムにしてみましょう。面倒なのでjQueryを利用して、次のように各入力要素のdisabledを解除してやります。

JavaScript

function syncerRecaptchaCallback( code )
{
	if(code != "")
	{
		$( '#syncer-recaptcha-form input , #syncer-recaptcha-form button' ).removeAttr( 'disabled' ) ;
	}
}

サンプルデモ

キャプチャ作業を終えたタイミングでフォームの操作不能状態を解除するサンプルデモです。

サンプルデモを見る

旧ブラウザなど非対応環境への対応

対応ブラウザ一覧

reCAPTCHAが対応しているのは、下記のバージョンを超えた各ブラウザです。

What are the minimum browser requirements for the checkbox reCAPTCHA widget?

Chrome 3.0.195
Firefox 3.0
Internet Explorer 7.0
Opera 10.10
Safari 4.0

What are the minimum browser requirements for the checkbox reCAPTCHA widget?より引用

コールバック関数名の指定

古いブラウザや、JavaScriptをOFFにしているユーザーへの配慮として、iframeを利用したコードを含んだnoscript要素を追加することが案内されています。下記コードはその引用です。5行目に、あなたの「Site key」をセットするのを忘れないで下さい。

HTML

<noscript>
	<div style="width: 302px; height: 352px;">
		<div style="width: 302px; height: 352px; position: relative;">
			<div style="width: 302px; height: 352px; position: absolute;">
				<iframe src="https://www.google.com/recaptcha/api/fallback?k={あなたのSite key}"
					frameborder="0" scrolling="no"
					style="width: 302px; height:352px; border-style: none;">
				</iframe>
			</div>
			<div style="width: 250px; height: 80px; position: absolute; border-style: none; bottom: 21px; left: 25px; margin: 0px; padding: 0px; right: 25px;">
				<textarea id="g-recaptcha-response" name="g-recaptcha-response"
					class="g-recaptcha-response"
					style="width: 250px; height: 80px; border: 1px solid #c1c1c1;
					margin: 0px; padding: 0px; resize: none;" value="">
				</textarea>
			</div>
		</div>
	</div>
</noscript>

代替用キャプチャの仕組み

非対応ブラウザやJavaScriptをOFFにしているユーザーに対しては、インラインフレーム内で作業をしてもらいます。ユーザーが画像に映った文字を入力すると、認証用コードがテキストフォームに表示されるので、ユーザーはそのコードを指定されたテキストボックスに入力後、フォームの送信ボタンをクリックする形になります。簡単に言うと、非対応環境のユーザーに対してもキャプチャが機能するということです。また、開発者は上記のコードを用意する以外に、プログラムを加える必要はありません。

実際に非対応環境のユーザーにはどのようなキャプチャが表示されるのか、開発者は簡単にテストすることができます。それには、ライブラリを読み込む時にfallback=trueというクエリを追加して下さい。

https://www.google.com/recaptcha/api.js?fallback=true

サンプルデモ

古いブラウザのユーザーが操作するreCAPTCHAのサンプルデモです。

サンプルデモを見る

ダウンロード

この記事で紹介してきたサンプルプログラムを配布しています。下地としてご利用いただければ幸いです。

ファイル一覧

SYNCER00045
recaptcha.php Download
recaptcha.html Download
recaptcha-validate.php Download
recaptcha-callback.php Download
recaptcha-callback.js Download
recaptcha-old-browser.php Download

ファイル名をクリックすると内容を確認できます。「Download Zip」をクリックするとファイル一式をダウンロードできます。

Download Zip