この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:7
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: reCAPTCHA
SEOタイトル: Google reCAPTCHA 完全ガイド (v2/v3)

この記事の要点
  • reCAPTCHA は Google のボット対策サービス。フォーム送信時に人間かどうかを判定
  • v2 はチェックボックス / 不可視タイプ、v3 はスコア型 (0.0 〜 1.0) でユーザー操作不要
  • フロント: https://www.google.com/recaptcha/api.js 読込 + Site Key
  • バックエンド: POST https://www.google.com/recaptcha/api/siteverify で Secret Key と一緒に検証
  • 代替: hCaptcha / Cloudflare Turnstile がプライバシー / 無料枠で人気

reCAPTCHA とは

Google reCAPTCHA は、Web フォームに対する自動化されたボット攻撃を防ぐためのサービスです。ユーザー登録・ログイン・コメント投稿などのフォームに組み込むことで、人間と機械を区別します。Google が無料で提供しており (一定リクエスト数まで)、世界で最も普及した CAPTCHA サービスです。

バージョンと特徴

バージョンユーザー体験仕組み用途
reCAPTCHA v2 Checkbox「私はロボットではありません」にチェックマウス操作・Cookie・行動分析定番。怪しい場合は画像チャレンジ追加
reCAPTCHA v2 Invisibleユーザー操作なしボタンクリック時に裏で判定UX を損ねたくないフォーム
reCAPTCHA v3完全に透明スコア (0.0〜1.0) を返す★ 推奨。ページ全体での挙動を分析
reCAPTCHA Enterprisev3 + α不正検知 API・有償大規模・金融系

キーの取得

  1. https://www.google.com/recaptcha/admin にアクセス (要 Google アカウント)
  2. 「+」ボタンで新サイトを登録
  3. reCAPTCHA タイプを選択 (v2 / v3)
  4. ドメインを登録 (example.com のように)
  5. Site Key (公開) と Secret Key (秘匿) が発行される

reCAPTCHA v2 (チェックボックス) の実装

フロントエンド

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>お問い合わせ</title>
  <script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
  <form method="POST" action="/contact">
    <input type="text" name="name" placeholder="名前">
    <textarea name="message"></textarea>

    <!-- ★ ここに reCAPTCHA ウィジェットが表示される -->
    <div class="g-recaptcha" data-sitekey="6Lc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"></div>

    <button type="submit">送信</button>
  </form>
</body>
</html>

バックエンド (PHP)

<?php
// フォーム送信時の検証
$token = $_POST['g-recaptcha-response'] ?? '';

if (empty($token)) {
    die('reCAPTCHA トークンが見つかりません');
}

$secret = getenv('RECAPTCHA_SECRET_KEY');

$response = file_get_contents(
    'https://www.google.com/recaptcha/api/siteverify?' . http_build_query([
        'secret'   => $secret,
        'response' => $token,
        'remoteip' => $_SERVER['REMOTE_ADDR'],
    ])
);

$result = json_decode($response, true);

if (!$result['success']) {
    error_log('reCAPTCHA failed: ' . json_encode($result['error-codes'] ?? []));
    die('CAPTCHA 検証に失敗しました');
}

// 成功: フォーム処理続行
processContactForm($_POST);

reCAPTCHA v3 (スコア型) の実装

v3 はユーザーに何も見えませんが、ページ操作から0.0〜1.0 のスコアが返ります (1.0 が人間らしい、0.0 がボットらしい)。0.5 を閾値にすることが多いです。

フロントエンド

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script src="https://www.google.com/recaptcha/api.js?render=6Lc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"></script>
</head>
<body>
  <form id="contactForm" method="POST" action="/contact">
    <input type="text" name="name">
    <textarea name="message"></textarea>
    <input type="hidden" name="recaptcha_token" id="recaptcha_token">
    <button type="submit">送信</button>
  </form>

  <script>
    document.getElementById('contactForm').addEventListener('submit', function(e) {
      e.preventDefault();
      grecaptcha.ready(function() {
        grecaptcha.execute('6Lc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', {action: 'submit_contact'})
          .then(function(token) {
            document.getElementById('recaptcha_token').value = token;
            e.target.submit();
          });
      });
    });
  </script>
</body>
</html>

バックエンド (PHP)

$token = $_POST['recaptcha_token'] ?? '';
$secret = getenv('RECAPTCHA_SECRET_KEY');

$ch = curl_init('https://www.google.com/recaptcha/api/siteverify');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query([
        'secret'   => $secret,
        'response' => $token,
        'remoteip' => $_SERVER['REMOTE_ADDR'],
    ]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 5,
]);
$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);

// v3 では success + score + action を確認
if (!$result['success']) {
    die('CAPTCHA 検証失敗');
}
if ($result['action'] !== 'submit_contact') {
    die('アクション不一致');
}
if ($result['score'] < 0.5) {
    error_log("Low score: {$result['score']}");
    die('ボットの疑い');
}

processContactForm($_POST);

Laravel での実装 (anhskohbo/no-captcha)

composer require anhskohbo/no-captcha
php artisan vendor:publish --provider="Anhskohbo\NoCaptcha\NoCaptchaServiceProvider"
// .env
// NOCAPTCHA_SITEKEY=6Lc_xxxxxxxxxxxxx
// NOCAPTCHA_SECRET=xxxxxxxxxxxxxx

// Blade テンプレート
<form method="POST" action="/contact">
    @csrf
    <input type="text" name="name">
    {!! NoCaptcha::renderJs() !!}
    {!! NoCaptcha::display() !!}
    <button type="submit">送信</button>
</form>

// Controller でバリデーション
$request->validate([
    'name' => 'required',
    'g-recaptcha-response' => 'required|captcha',
]);

レスポンスフィールド

フィールド意味v2v3
success検証成功かありあり
score0.0 (ボット) 〜 1.0 (人間)-あり
actionexecute 時のアクション名-あり
challenge_ts判定タイムスタンプありあり
hostname判定が行われたドメインありあり
error-codesエラー詳細ありあり

代替サービス

サービス特徴無料枠
hCaptchaプライバシー重視、Cloudflare 採用月 100 万件まで無料
Cloudflare Turnstile不可視・無料・無制限完全無料
FriendlyCaptchaGDPR 準拠、EU 拠点有償 (一部無料)
MTCaptcha多言語・カスタマイズ豊富月 1 万件無料

FAQ

Q: v3 のスコア閾値はいくつにすべき?
A: Google 公式は 0.5 を推奨。最初は記録のみで運用してログを見て調整するのが定石。0.3 未満を即拒否、0.3〜0.7 はメール認証等の追加、0.7+ は通すといった段階運用も。

Q: localhost で開発したい
A: reCAPTCHA 管理画面のドメイン欄に localhost を追加すれば動作します。

Q: 1 ページに複数 reCAPTCHA を置きたい
A: v2 では grecaptcha.render() でウィジェット ID を指定して複数描画可能。v3 では action を変えて execute を複数回呼びます。

📸 参考画像

※ 旧バージョンから引き継いだ参考画像です。手順・図解の補助としてご覧ください。

参考画像