AQ Tech Blog

ECサイトにおけるreCAPTCHA v3認証導入の実践【ボット被害とおさらばしたい方へ】

作成者: musheng.chen|2024年09月28日

はじめに

この記事では、私が関わったECサイト開発の一環として、GoogleのreCAPTCHA v3を導入した実際の開発経験を基に、その背景と具体的な運用方法をシェアします。
今回のオンライン販売システムでは、ユーザーがクーポンを申請する際にボット対策としてreCAPTCHA認証を利用し、正当なユーザーかどうかを判断する仕組みを実装しました。

本文は、まずreCAPTCHA v2とv3の違いを簡単に説明し、その後、v3を選んだ理由と実際の導入方法について具体的なコード例を交えて解説します。

記事の目的と狙い

  • ECサイトでのボット対策に興味がある開発者向けに、reCAPTCHA v3の概要と実装方法を紹介します
  • reCAPTCHA v2とv3の違いを理解し、v3の利点を活かした実装のヒントを提供します
  • ボットからの不正リクエストを防ぐための実際の開発経験をもとに、現場での運用例をシェアします

背景・課題

ECサイトでは、クーポンや特典の申請システムを狙ったボットアクセスが問題になることが多くあります。
今回のプロジェクトでも、ボットによる不正なクーポン申請が大量に発生し、存在しないメールアドレスにクーポンが送られることで、多くのバウンスメールが発生し、重要な不達通知が埋もれてしまう問題がありました。

背景詳細

  1. ボットによる不正なクーポン取得が大量に発生し、ログが圧迫され、正規ユーザーの操作が確認できなくなる恐れがありました。
  2. バウンスメールの数が急増し、システム管理者にとって見逃せない重要なアラートが埋もれるリスクがありました。
  3. 将来的にECサイトのアクセス増加が見込まれており、ボット対策は不可欠とされていました。


解決策

この問題を解決するために、ユーザーがクーポンを申請する際に、Google reCAPTCHAを導入して、ユーザーが人間かボットかを判断するプロセスを追加しました。
特に、今回の導入ではreCAPTCHA v3を使用し、ユーザーの利便性を損なわずに高精度なボット判定を行うことが可能となりました。

処理概要

  1. クーポン申請画面でreCAPTCHAを導入
    ユーザーがクーポン申請を行う際に、reCAPTCHAを利用してそのユーザーがボットでないことを確認する処理を実装します。
  1. スコアベースの判定
    reCAPTCHA v3のスコア機能を活用し、0.5以上のスコアを獲得したユーザーのみがクーポン申請を成功させられるように設定します。
  1. API連携
    クーポン申請の際、Googleのsiteverify APIにトークンを送信し、その結果に基づいてクーポンを発行するかどうかを決定します。

reCAPTCHA v2とv3の違い

reCAPTCHA v2

  • ユーザーに「私はロボットではありません」というチェックボックスを表示し、クリックして認証する方式。
  • あるいは、画像認証でユーザーに特定の画像を選択させる方式が使われます。
  • ボットと人間を視覚的に判定しますが、ユーザーにとって操作の手間が増える場合があります。

reCAPTCHA v3

  • v3は、完全にユーザーの操作を邪魔しない無侵入型のソリューションです。
  • ユーザーの行動やアクセスパターンに基づき、Googleがボットか人間かをスコア(0〜1)で判断します。
  • 設定する基準値以上のスコアが出れば人間と判断し、基準値未満であればボットと判定します。
  • そのため、ユーザーの操作性を損なわずに高精度な判定が可能です。

今回のプロジェクトでは、reCAPTCHA v3を採用しました。これは、ユーザーに追加の操作を要求せずに、バックグラウンドで正確にボットを検出できるためです。

reCAPTCHA共有キーの発行

まず最初に、Google reCAPTCHA認証のコンソールサイトにアクセスし、v3の「サイトキー」と「シークレットキー」を取得していきます。

  1. Google reCAPTCHA管理コンソールにアクセスします。
    reCAPTCHA管理ページへアクセスして、「v3 Admin Console」をクリックします。
  1. 新しいサイトを作成します。
    以下のAdmin管理ページで、右上の「+」ボタンをクリックします。
  1. サイト情報を登録します。
    • ラベル

      • ラベルは分かりやすいものを入力します。(例:サイトドメイン名など)
    • reCAPTCHAタイプ

      • 「スコアベース(v3)」を選択してください。
    • ドメイン

      • reCAPTCHA v3を利用したいサイトのドメインを入力します。
    • GOOGLE CLOUD PLATFORM

      • 以前にGoogle Cloud Platformを使用した事がある場合にはプロジェクト名が記載されています。
    • 最後に「送信」ボタンを押下します。

  1. サイト情報を登録完了。
    「サイトキー」と「シークレットキー」が生成されます。この2つのキーを使用します。

LaravelにreCAPTCHA v3を搭載する方法

以下は個人テスト用に実装したreCAPTCHA v3のコード例です。 実際のプロジェクトコードではなく、汎用的なPHP実装例に基づいて説明します。

環境

  • PHP v8.3.11
  • Laravel v10.41.0

環境変数(.env)設定

先ほど発行したサイトキーとシークレットキーを記入します。
※以下はダミーのキーを使っています。

  • .env
RECAPTCHA_SITE_KEY=6LdyWDgqAAAAAAUNIUTGGTYFMiB7J4ixxxxxxxxx
RECAPTCHA_SECRET_KEY=6LdyWDgqAAAAADtOZU-Y10EhL4-2qxxxxxxxxxxx


configファイルを追加

  • config/services.php
<?php

return [
'recaptcha' => [
'site_key' => env('RECAPTCHA_SITE_KEY'),
'secret_key' => env('RECAPTCHA_SECRET_KEY'),
],
];


HTMLでreCAPTCHAトークンを取得

reCAPTCHAを設定したいビューファイルを開きます。

  • packages/Webkul/Shop/src/Resources/views/components/layouts/footer/index.blade.php

設定したいフォームにinputタグをいれておきます。

<input type="hidden" name="recaptchaToken" id="recaptchaToken">

JavaScriptを使って<script>タグに下記を動的に加えます。

<script>
function loadRecaptchaScript() {
const script = document.createElement('script')
script.src = `https://www.google.com/recaptcha/api.js?render={{ config('services.recaptcha.site_key') }}`
script.async = true
script.defer = true
script.onload = () => {
console.log('reCAPTCHA is loaded and ready.')

grecaptcha.ready(async () => {
const token = await grecaptcha.execute('{{ config('services.recaptcha.site_key') }}', {action: 'submit'})
document.getElementById('recaptchaToken').value = token
})
}

document.head.appendChild(script)
}

window.addEventListener('load', function () {
loadRecaptchaScript()
})
</script>


reCAPTCHAトークンの検証

フォーム送信を処理する時に、reCAPTCHA トークンを検証するロジックを追加します。

  • packages/Webkul/Shop/src/Http/Controllers/SubscriptionController.php
<?php
class SubscriptionController extends Controller
{
public function store()
{
$recaptchaToken = request()->input('recaptchaToken');
$recaptchaSecret = config('services.recaptcha.secret_key');

$response = Http::asForm()->post('https://www.google.com/recaptcha/api/siteverify', [
'secret' => $recaptchaSecret,
'response' => $recaptchaToken,
'remoteip' => request()->ip(),
]);

$recaptchaData = json_decode($response->body());

if (! $recaptchaData->success || $recaptchaData->score < 0.5) {
Log::error('recaptcha error', ['recaptcha' => $response->body()]);

return redirect()->back()->withErrors(['recaptcha' => 'reCAPTCHA verification failed.']);
}
Log::info('recaptcha success', ['recaptcha' => $response->body()]);

// メールサブスクリプションのロジックを処理します
}
}

こちら、スコアが0.5以上なら「成功」となり、通常どおりの処理が行われます。
スコアが0.5より少ない場合には、「ユーザーは人間ではないのでは?」と判断され、 それ以降の処理は実行されません。

実行が成功したときのログ。

さいごに

reCAPTCHA v3は、ユーザーに煩わしさを与えずに高精度なボット判定を行える非常に便利なツールです。
特に、ECサイトのように大量のアクセスが見込まれる環境では、reCAPTCHA v3を導入することで、システムの負担を減らし、正当なユーザーに優しい環境を提供することが可能になります。

同じようにボット被害に悩んでいたら、参考にしてくださいね。

最後までお読みいただきありがとうございました!

参考記事

reCAPTCHA v3公式ガイド
よくある質問
Google reCAPTCHA v3認証の導入方法