こんにちは、吉田です。
今日は、Google Invisible reCAPTCHAの導入を「やってみた」投稿です。
フォームへのSPAM登録にお困りで、「reCAPTCHA入れると見栄えが変わるなぁ」と感じておられる方や、
「いつかウチのサイトが攻撃されるかも」と考えておられる方へのご参考になればと思います。
「私はロボットではありません」への苦手意識
突然ですが、私はreCAPTCHAの「私はロボットではありません」チェックをやや苦手に感じています。
同意を強要されているような感覚と、チェックボックスがぐるぐる回るあいだ合格発表を待つような気持ちになるからです。
そして、割と高い頻度で認証が必要となり、不合格にされたようで少しがっかりします。
そんな私にうってつけ?なのかどうか、今回そのチェックが不要なInvisible reCAPTCHAというものをフォームに適用してみました。
やることは通常のreCAPTCHAとほとんど一緒
Invisible reCAPTCHAの導入は簡単で、以下の3つのステップで実現できます。
サーバ側処理の作成に、多少手がかかる程度です。
- GoogleのサイトでreCAPTCHAを取得
- ブラウザ(クライアント)側にreCAPTCHAのウィジェットを設置
- サーバ側でreCAPTCHAが送信したトークンをチェック
GoogleのサイトでreCAPTCHAを取得
reCAPTCHAのページから取得時に「Invisible reCAPTCHA」を選択します。
対象ドメイン名を事前に確認しておきましょう。Googleアカウントさえあれば、簡単です。
Chromeで翻訳すればほぼわかりますが、設定項目の内容です。
- Label:管理名称
- Choose the type of reCAPTCHA:取得するreCAPTCHAの種別(今回はInvisible reCAPTCHAを選択)
- Domains:reCAPTCHAを設置するドメイン(画像は複数指定の例のため、サブドメインまで記載しなくてもOK)
- Accept the reCAPTCHA Terms of Service:規約の承諾
- Send alerts to owner:トラフィック異常時にオーナーにメール通知
見落としそうなポイントとして[Register]ボタンで登録した後、一覧から作成したreCAPTCHAを選択し、[Advanced Settings]の設定も確認しておいてくださいね。
このように、かなり控えめに表示されています。
展開すると以下の設定項目が表示されます。
- Owners:このreCAPTCHAを共有するオーナー
- Security Preference:セキュリティの強度を3段階で設定
実際に攻撃があった場合、この管理画面で状況をグラフなどで確認できます。
設定が終わったら、サイトキー(Site Key) と シークレットキー(Secret Key)を取得し、ガイドを参考にさくさく実装しましょう。
ブラウザ(クライアント)側にreCAPTCHAのウィジェットを設置
まずはHTMLの加工から開始します。
1.スクリプトの呼び出し
指定のスクリプトをheadタグ内に記載
<script src='https://www.google.com/recaptcha/api.js'></script>
2.reCAPTCHAチェックOK時のコールバック関数作成
1 2 3 |
function onSubmit(token) { document.getElementById("[フォームのid]").submit(); } |
3.reCAPTCHA判定中エラー時のコールバック関数作成
モバイルでの利用も多いので、通信エラー時の動作も考慮して、エラーメッセージを表示するコールバック関数を記述してはいかがでしょう。
1 2 3 |
function onReCaptchaError() { [エラーメッセージを記載しているdivタグなどを表示する処理] } |
エラーの後処理としてreCAPTCHAの状態をリセットすることも可能ですが、結局、ロード時にエラーになってしまう事が多いので、この程度で良さそうです。
4.送信ボタンの加工
送信ボタンを加工します(data-callbackとerror-callbackの指定は先程作成したもの)。
1 2 3 4 |
<button class="g-recaptcha" data-sitekey="[サイトキー]" data-callback='onSubmit' error-callback='onReCaptchaError'>送信</button> |
以上、4ステップでなんとも簡単にクライアント側の設置は完了します。
この時点でアップしたHTMLを確認すると、「私はロボットではありません」チェックではなく、フォームの右下隅にreCAPTCHAのロゴが表示されます。
文字が切れているのが気にはなるものの、保護しているという情報は表示されるということですね。
控えめなこのロゴにマウスを持ってくると、「ビュー」っとスライドして利用規約へのリンクも表示されます。
スマートフォンでも同様に表示されます。
上記のスクリプト(api.js)の呼び出し時に"hl"というパラメータに言語コードを設定すると、ブラウザの環境にかかわらず設定した言語で表示されます。
英語(en)の場合はロゴ表示の時点で利用規約まで文字が表示されます。
そして、「送信」ボタンを押下すると、認証の必要がない場合はそのまま送信されます。
イイです!チェックボックスがぐるぐる回らない!「ホントに確認した?」と感じるくらい自然です。
ただし、認証の必要があると判定された場合は、画像選択のモーダルダイアログが表示されます。
認証要否の判定基準は明確にはされていませんが、前述のAdvanced SettingsにあるSecurity Preference設定が影響します。
ブラウザの状態や接続IPアドレスを元に判定されるようです。
Googleにログインしている場合は表示されなかったり、逆にそのせいで表示されたり、といったことも起こります。
ところで、音声での認証機能があるのはご存知でしょうか。
上記のダイアログにあるヘッドフォンのボタンを押すと、音声認証に切り替わります。
再生ボタンで流れる音声を聞いて、内容をテキストに入力するだけです。
しかし、残念ながら、現時点の音声は英語のみで雑音がひどく、私は数回しか正解できませんでした。
耳に自信のある方は、reCAPTCHAを見かけたら是非試してみてください。
音声認証は少し前のスマートフォンやInternet Explorer 11ではページ上で再生されないため、「↓」ボタンでダウンロードしてから確認します。
サーバ側でreCAPTCHAが送信したトークンをチェック
続いてはサーバー側の実装です。
リクエストに"g-recaptcha-response"パラメータとしてトークンが渡されるので、チェック用URLにSecret Keyと一緒にPOSTすると結果のJSONが返されます。
チェック時のPOSTパラメータの内容
- secret:シークレットキー
- response:クライアントから受け取ったトークン
- remoteip:リクエストのリモートIPアドレス(任意)
回答されるJSONの内容
1 2 3 4 5 6 |
{ "success": true|false, "challenge_ts": timestamp, "hostname": string, "error-codes": [...] } |
- success:成功の場合、true
- challenge_ts:チェックしたタイムスタンプ
- hostname:チェックした際のホスト名
- error-codes:エラーの場合内容を返却
トークンチェックエラーが失敗した場合はbotからの攻撃の可能性があるので、セッションがあるなら無効化しエラーページを表示すれば実装は完了です。
「botじゃないですか?」という直球メッセージも難有りなので、適当なエラーメッセージを表示します。
留意事項
Invisible reCAPTCHAのメリット
メリットとして以下の2点が挙げられます。
- レイアウトがスッキリしてイメージを損なわない
- トークンのタイムアウトを気にしなくて良い
トークンはreCAPTCHA 認証時に払い出されるため、既存のreCAPTCHA v2の場合、チェックした後フォームを放置するとタイムアウトと判定されます。
Invisible reCAPTCHAの場合は送信ボタンと連動するので、対応を深く考える必要がありません。
Invisible reCAPTCHAのデメリット
デメリットとして以下の点への考慮が挙げられます。
- 突然、画像認証が表示される違和感
画像認証が必要と判定された場合、「私はロボットではありません」からの流れではなく、送信したと思ったら「画像を選択してください」と指示されることになります。
reCAPTCHAのロゴが表示されているものの、対応いただけるか考慮する必要がありそうです。
動作環境について
Googleが表明しているreCAPTCHAの推奨環境は以下の最新メジャーバージョン2世代と記載されています。
Windows, Linux, Mac
- Chrome
- Firefox
- Safari
- IE
- Edge
Mobile
- Chrome
- Safari
- Android native browser
確認したところ、現時点のInvisible reCAPTCHAはInternet Explorerは10以降、Androidの標準ブラウザは4.4以降で機能するようです。
クライアントで動的にフォームや送信ボタン制御をおこなっている場合
HTMLレイアウトの動的変更をおこなっている場合、クライアント実装が今回の対応とは若干異なることがあるので注意が必要です。
スクリプト(api.js)への参照を非同期としたり、「ロード後の送信ボタン」をサイトキーやコールバック関数に紐付ける必要があります。
詳細はGoogleのreCAPTCHAガイドに記載がありますので、ご参考に。
他に、submit
<input id='submit' type="submit" value="送信">に紐付ける場合は、submit自体によるフォームの送信はキャンセルされるようです。
reCAPTCHA認証通過時のコールバックでフォームのsubmit()が必要となる模様ですので、ご注意ください。
まとめ
Invisible reCAPTCHAは名前の通り、フォームの見映えがほぼそのままという点が優れています。
入力前の「させられる」感を多少は軽減できるように思います。
現時点でGoogleからはreCAPTCHA v3のベータ版がリリースされています。スコアによる判定にシフトしていくようです。
機会があれば、試して投稿します。
reCAPTCHAでも画像や選択のバリエーション、仕組みが何度も見直されているように、フォーム管理者のSPAM登録との戦いは継続が必要です。
フォームと、サーバなどのアクセス監視が別部門管理、というケースが多いため早期対応が難しいことも多いと思います。
簡単なアプリケーション側での対応を検討される際、本投稿でreCAPTCHAを身近に感じて頂ければありがたいです。
あと、弊社クラウドサービスSynergy!のフォームは、Invisible reCAPTCHAカスタマイズ可能です。
製品ページのお問い合わせフォームやお電話、既にご利用でしたら弊社営業やカスタマーサポートへお問い合わせください(宣伝)!!
※本ブログでは説明のため、Google reCAPTCHAの画面キャプチャを引用しております。
Google and the Google logo are registered trademarks of Google LLC, used with permission.
Comments
reCAPTCHAのバージョンアップにより、動作環境が変わったため、
確認できたブラウザのバージョンを更新しました。
Internet Explorer 9以降⇒10以降
Androidの標準ブラウザ4.2以降⇒4.4以降