reCAPTCHA
reCAPTCHA は悪質なボットからWebサイトを的るための無料のサービスです。Googleが提供するサービスで、2018年10月現在、第3世代のベータ版が提供されています。
第1世代と第2世代はユーザーによる入力が必要で、これがなかなか面倒だったりします。
最近では第1世代のものはあまり見ません。第2世代の「私はロボットではありません」と画像の選択は比較的よく見ます。
いずれもユーザー操作が必要ですが、第3世代ではユーザー操作なしでも人間とボットの識別を行えるようになるようです。現在β版が後悔されています。
Invisible reCAPTCHA
ユーザー操作不要の reCAPTCHAサービスが、Invisible reCAPTCHA と呼ばれるものです。一応上のページを見ると、v2のくくりになっているので第2世代なのでしょうか。
いずれにせよ「私はロボットではありません」のチェックをせずとも、目に見えないところで自動的に人間かボットかの判定をしてくれるため、ユーザーによる操作の手間を減らすことが可能です。ただし、ボットだと判定された場合には、おなじみの CAPTCHA が表示されることになります。
ちなみにどのようにしてボットであると判定するかは公開されていないようです。
Webサイトへの導入方法
以下、 Invisible reCAPTCHA をWebサイトに導入する方法をまとめます。
登録とkeyの発行
まずは、reCAPTCHAを利用するための登録をする必要があります。上記サイトから登録してください。
入力項目は次の通りです。
項目 | 説明 |
---|---|
Label | サイトを識別する文字列。 |
Choose the type of reCAPTCHA | 利用するreCAPTCHAの種類。今回はInvisibleを選択 |
Domains | 導入するサイトのドメイン。複数入力可能。 |
あとは利用規約に同意して、アラートの送信が必要であればチェックを入れて登録します。
登録が完了すると、Site key
及び Secret key
が発行されます。これを失くさないように保存しておきましょう。
Webサイトへの導入
発行された Site Key
とスクリプトをWebサイトに埋め込みます。
まずは、reCAPTCHA
用のスクリプトを読み込みます。
<script src='https://www.google.com/recaptcha/api.js'></script>
次に、サブミット用のボタンを用意します。YourOnSubmitFn
は、コールバック関数です。実際にサブミットを行う関数を用意して、ここに設定しておきます。
<button
class="g-recaptcha"
data-sitekey="your_site_key"
data-callback="YourOnSubmitFn">
Submit
</button>
一例としては次のような形になります。
<html>
<head>
<title>reCAPTCHA demo: Simple page</title>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
function onSubmit(token) {
document.getElementById("demo-form").submit();
}
</script>
</head>
<body>
<form id='demo-form' action="?" method="POST">
<button class="g-recaptcha" data-sitekey="your_site_key"
data-callback='onSubmit'>Submit</button>
<br/>
</form>
</body>
</html>
このHTMLを表示すると、画面右下に次のような画像が表示されます。
もし設定に間違いがあれば、この画像の文字列が赤字でエラーになります。例えば、ローカルで試そうとした場合、次の文言が表示されます。
localhost は、このサイトキーでサポートされているドメインのリストに含まれていません
正しく表示されたら動作を確認してみましょう。ボタンを押すと、最初の何度かはおなじみの画像選択のCAPTCHAが表示されると思います。間違えるとSubmitができないことが確認できます。
サーバー側の実装
ここまでで reCAPTCHA
をブラウザ側で動かすことができました。
ただし、これだけだと Javascript を無効化することで突破される可能性があります。(Invisible reCAPTCHA 自体がJavascriptのAPIで提供されるため。)
ということで、実際には reCAPTCHA を突破した際に発行されるトークンをサーバー側に送信し、受け取ったサーバーでAPIをたたいて認証を確認する必要があります。
やることは簡単で、以下のURLにリクエストを投げることで認証済かどうかを返してくれます。それを見て認証済の場合のみ、処理を実行するようにすればOKです。
https://www.google.com/recaptcha/api/siteverify?secret=[シークレットキー]&response=[トークン]
トークン は、reCAPTCHA
突破時に発行されるものです。上の例だとコールバック関数の引数に渡されているそれです。submit時じは、g-recaptcha-response
という名前のパラメータで自動的にFormに付加されて送信されています。なのでこれと、発行されたシークレットキーでリクエストを投げてやればよいです。
実装はサーバーの言語環境によって方法は変わってきますが、試しに発行されたトークンとキーの組み合わせで、ブラウザのアドレスバーに直打ちすると次のようなレスポンスが確認できます。
{
"success": true,
"challenge_ts": "2018-10-01T07:19:10Z",
"hostname": "webbibouroku.com"
}
success
が認証結果です。ここを見て正しく認証されているかどうかを判定するとよいでしょう。
詳しい仕様は、以下の公式ページをご確認ください。
以下、PHPでの実装例です。
public function checkReCaptcha() {
$secret_key = 'xxxxxxxxxxxx'; // 発行されたキーを入れる
$token = $_POST['g-recaptcha-response'];
$url = 'https://www.google.com/recaptcha/api/siteverify';
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'secret' => $secret_key,
'response' => $token
]),
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response)->success;
}
リクエストを投げて認証済かどうかの判定結果を true
or false
で返す関数です。$secret_key
については発行されたキーを入れてください。token部分は、reCAPTCHAが自動的にパラメータとして埋め込んでポストされた値を使っています。
以上。
コメントを書く