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

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

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong>reCAPTCHA</strong> は Google のボット対策サービス。フォーム送信時に人間かどうかを判定</li><li>v2 はチェックボックス / 不可視タイプ、<strong>v3 はスコア型</strong> (0.0 〜 1.0) でユーザー操作不要</li><li>フロント: <code>https://www.google.com/recaptcha/api.js</code> 読込 + Site Key</li><li>バックエンド: <code>POST https://www.google.com/recaptcha/api/siteverify</code> で Secret Key と一緒に検証</li><li>代替: <strong>hCaptcha</strong> / <strong>Cloudflare Turnstile</strong> がプライバシー / 無料枠で人気</li></ul></td></tr></table>
<h2>reCAPTCHA とは</h2>

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

<h2>バージョンと特徴</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>バージョン</th><th>ユーザー体験</th><th>仕組み</th><th>用途</th></tr></thead>
<tbody>
<tr><td><strong>reCAPTCHA v2 Checkbox</strong></td><td>「私はロボットではありません」にチェック</td><td>マウス操作・Cookie・行動分析</td><td>定番。怪しい場合は画像チャレンジ追加</td></tr>
<tr><td><strong>reCAPTCHA v2 Invisible</strong></td><td>ユーザー操作なし</td><td>ボタンクリック時に裏で判定</td><td>UX を損ねたくないフォーム</td></tr>
<tr><td><strong>reCAPTCHA v3</strong></td><td>完全に透明</td><td>スコア (0.0〜1.0) を返す</td><td>★ 推奨。ページ全体での挙動を分析</td></tr>
<tr><td><strong>reCAPTCHA Enterprise</strong></td><td>v3 + α</td><td>不正検知 API・有償</td><td>大規模・金融系</td></tr>
</tbody>
</table>

<h2>キーの取得</h2>

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

<h2>reCAPTCHA v2 (チェックボックス) の実装</h2>

<h3>フロントエンド</h3>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!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></code></pre>
<h3>バックエンド (PHP)</h3>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php"><?php
// フォーム送信時の検証
$token = $_POST[&apos;g-recaptcha-response&apos;] ?? &apos;&apos;;

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

$secret = getenv(&apos;RECAPTCHA_SECRET_KEY&apos;);

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

$result = json_decode($response, true);

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

// 成功: フォーム処理続行
processContactForm($_POST);</code></pre>
<h2>reCAPTCHA v3 (スコア型) の実装</h2>

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

<h3>フロントエンド</h3>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!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(&apos;contactForm&apos;).addEventListener(&apos;submit&apos;, function(e) {
      e.preventDefault();
      grecaptcha.ready(function() {
        grecaptcha.execute(&apos;6Lc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&apos;, {action: &apos;submit_contact&apos;})
          .then(function(token) {
            document.getElementById(&apos;recaptcha_token&apos;).value = token;
            e.target.submit();
          });
      });
    });
  </script>
</body>
</html></code></pre>
<h3>バックエンド (PHP)</h3>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">$token = $_POST[&apos;recaptcha_token&apos;] ?? &apos;&apos;;
$secret = getenv(&apos;RECAPTCHA_SECRET_KEY&apos;);

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

$result = json_decode($response, true);

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

processContactForm($_POST);</code></pre>
<h2>Laravel での実装 (anhskohbo/no-captcha)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-bash">composer require anhskohbo/no-captcha
php artisan vendor:publish --provider="Anhskohbo\NoCaptcha\NoCaptchaServiceProvider"</code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">// .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([
    &apos;name&apos; => &apos;required&apos;,
    &apos;g-recaptcha-response&apos; => &apos;required|captcha&apos;,
]);</code></pre>
<h2>レスポンスフィールド</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>フィールド</th><th>意味</th><th>v2</th><th>v3</th></tr></thead>
<tbody>
<tr><td>success</td><td>検証成功か</td><td>あり</td><td>あり</td></tr>
<tr><td>score</td><td>0.0 (ボット) 〜 1.0 (人間)</td><td>-</td><td>あり</td></tr>
<tr><td>action</td><td>execute 時のアクション名</td><td>-</td><td>あり</td></tr>
<tr><td>challenge_ts</td><td>判定タイムスタンプ</td><td>あり</td><td>あり</td></tr>
<tr><td>hostname</td><td>判定が行われたドメイン</td><td>あり</td><td>あり</td></tr>
<tr><td>error-codes</td><td>エラー詳細</td><td>あり</td><td>あり</td></tr>
</tbody>
</table>

<h2>代替サービス</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e8f5e9"><th>サービス</th><th>特徴</th><th>無料枠</th></tr></thead>
<tbody>
<tr><td><strong>hCaptcha</strong></td><td>プライバシー重視、Cloudflare 採用</td><td>月 100 万件まで無料</td></tr>
<tr><td><strong>Cloudflare Turnstile</strong></td><td>不可視・無料・無制限</td><td>完全無料</td></tr>
<tr><td><strong>FriendlyCaptcha</strong></td><td>GDPR 準拠、EU 拠点</td><td>有償 (一部無料)</td></tr>
<tr><td><strong>MTCaptcha</strong></td><td>多言語・カスタマイズ豊富</td><td>月 1 万件無料</td></tr>
</tbody>
</table>

<h2>FAQ</h2>

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

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

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