グーペ ECブログリレー

グーペのお問い合わせフォームにreCAPTCHA v2を導入した話

グーペ ECブログリレー

こんにちは!EC事業部エンジニアのenduと言います。
普段はCRE/QAチームに所属しており簡単にホームページを作れる「グーペ」というサービスでソフトウェアエンジニアをしています。業務内容としてはお客様から来たお問い合わせ対応、機能改善、新規機能開発を行っています。

今回は1月にグーペで提供を開始した「reCAPTCHA」機能の導入方法や検証した内容をご紹介したいと思います。

お問い合わせへのスパム・迷惑メール対策に!「reCAPTCHA」機能リリース

  1. 解決したかった課題
  2. reCAPTCHAを使って自動でスパム判定を行う
    1. reCAPTCHAタイプについて
    2. reCAPTCHAの導入方法について
  3. グーペでのreCAPTCHA運用方法について
  4. まとめ

解決したかった課題

グーペではホームページに訪れた訪問者がホームページを管理しているグーペ利用者にお問い合わせを送れる「お問い合わせフォーム」という機能を提供しています。 この「お問い合わせフォーム」を悪用して、攻撃者によってグーペ利用者にスパムメールが送られる問題が定期的に発生していました。 これまではサービス側で攻撃者のIPアドレスをブロックリストに入れたり、グーペ利用者側で「フィルター設定」を使って対処して頂く案内も出していました。しかし、どちらも手動での対応が必要で、かつ攻撃者側でメールアドレスやIPアドレスを変更されてしまうと簡単に突破されてしまうという課題がありました。

reCAPTCHAを使って自動でスパム判定を行う

上記の課題を解決する為、Googleが提供しているreCAPTCHAを使って自動で判定を行いスパムメールを防ぐ事にしました。

reCAPTCHAタイプについて

reCAPTCHAにはreCAPTCHA v2reCAPTCHA v3の2種類があります。

reCAPTCHA v2はチェックボックスへのチェックや画像の選択によってスパム判定を行い、reCAPTCHA v3は独自のスコアリングアルゴリズムでスパム判定を行います。 チーム内で相談した結果reCAPTCHA v3だとスコア判定のしきい値をグーペ利用者側で調整する必要がある為、今回はreCAPTCHA v2で進める事にしました。

reCAPTCHA v2には2つのタイプがあります。

Checkboxタイプ Invisibleタイプ
「私はロボットではありません」チェックボックスを使用してリクエストを検証します チェックボックスを非表示にしてバックグラウンドでリクエストを検証します

Invisibleタイプは「私はロボットではありません」のチェックボックスが非表示になりますがデフォルト設定ではreCAPTCHAバッチが表示されます。

reCAPTCHAバッチも非表示にしたい場合は利用規約とプライバシーポリシーに関する文言をサイトに表示すれば良いとFAQに書かれています。

This site is protected by reCAPTCHA and the Google
    <a href="https://policies.google.com/privacy">Privacy Policy</a> and
    <a href="https://policies.google.com/terms">Terms of Service</a> apply.

当初ホームページの訪問者への影響が少ないInvisibleタイプで導入を進めようと検証を行っていました。しかしドキュメントの手順通り実装を行ってもJavaScriptの判定処理の調整が難しく実現に時間がかかると判断した為、Checkboxタイプに変更して導入を進める事になりました。

reCAPTCHAの導入方法について

reCAPTCHAの導入にはGoogle reCAPTCHAの管理画面でドメイン登録してサイトキーシークレットキーを発行する必要があります。

それぞれの役割は以下の通りです。

  • サイトキー: クライアントでreCAPTCHAのチェックボックスを表示する為に必要な値
  • シークレットキー: サーバサイドでreCAPTCHAを使ったスパム判定を行う際に必要な値

クライアント側での実装

クライアント側でreCAPTCHAのチェックボックスを表示させるのは簡単です。 https://www.google.com/recaptcha/api.jsを読み込んでformタグ内にdivタグのclassg-recaptchadata-sitekey属性に登録しておいたサイトキーを設定する事で「私はロボットではありません」のチェックボックスが表示されます。

<html>
  <head>
    <title>Demo Page</title>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
  </head>
  <body>
    <form action="?" method="POST">
      <div class="g-recaptcha" data-sitekey="your_site_key"></div>
      <br/>
      <input type="submit" value="Submit">
    </form>
  </body>
</html>

「私はロボットではありません」チェックが完了すると、g-recaptcha-responseというnameでトークンが入ります。

<input type="hidden" name="g-recaptcha-response" value="****">

サーバ側での実装

次にサーバ側でのPHPを使った実装例を紹介します。

事前に登録したシークレットキーとg-recaptcha-responseの値を使ってreCAPTCHAのAPIでスパム判定を行います。 以下にサンプルコードを載せておきます。

use GuzzleHttp\Client;

$httpClient = new Client([
    'base_uri' => 'https://google.com/recaptcha/api/',
]);
$recaptchaResponse = $_POST['g-recaptcha-response'];
$response = $httpClient->request('POST', 'siteverify', [
    'query' => [
        'secret' => $your_secret_key,
        'response' => $recaptchaResponse,
    ]
]);

if ($response->getStatusCode() == 200) {
  $decodedBody = json_decode($response->getBody());
  if ($decodedBody->success) {
      return true;
  } else {
      return false;
  }
}

公式ドキュメントにはJavaScriptを使った実装方法も記載されているので参考に見てください。

グーペでのreCAPTCHA運用方法について

グーペではr.goope.jpでホームページを公開する方法と独自ドメインで公開する方法があります。
r.goope.jpでホームページを公開されている場合は、お問い合わせフォームには自動でreCAPTCHAのチェックボックスが表示されます。前述したreCAPTCHAのサイトキーとシークレットキーはドメインに紐づくもので、予めgoope.jpで発行したものを使っているからです。

一方で独自ドメインを設定した場合はグーペ側で発行したサイトキーとシークレットキーが使えない為reCAPTCHAのチェックボックスが表示されなくなります。なので、独自ドメインを設定して頂いているグーペ利用者には自身で発行したサイトキーとシークレットキーが登録が出来る専用の登録フォームを用意する事で対処しています。この様にしてグーペを利用されている全員がreCAPTCHAを使えるように運用を行っています。

まとめ

グーペのお問い合わせフォームにreCAPTCHA v2を導入した事例を紹介しました。 今はまだreCAPTCHA v2は「お問い合わせフォーム」にしか提供できてませんが将来的には他のページにも出せるようにしたいので、引き続きグーペを安全に使って頂けるよう開発を続けていこう思います。