【reCAPTCHA v3】二通りの使い方とFirebase App Check。サイトキー・シークレットキーの役割と当サイトの実装例
📝 記事について: 本記事は、50近辺のくたびれた貧乏なおっさんの筆者が、「新しい技術」「このサービスおもしろいな~~」「このアプリおもしろいな~~」「ほしいな~~」「かいたいな~~」と思った製品・サービスについて、公開情報を調べてまとめたものです。実際に製品やサービスを使用・体験したわけではありません。内容の正確性については、必ず公式情報やデータソースをご確認ください。
reCAPTCHA v3には、おもに二通りの使い方があります。ひとつはreCAPTCHAを直接使う方法(サイトキー+シークレットキーでGoogleのsiteverify APIに検証依頼)、もうひとつはFirebase App Check経由で使う方法です。本記事では、それぞれの違い、キーの役割、当サイトでの実装例を整理して解説します。
Core Insights
- 二通りの使い方: ①直接検証(siteverify API) ②Firebase App Check経由
- 直接検証: シークレットキーをサーバーに設定し、siteverify APIでトークンを検証する。
- App Check: シークレットキー不要。Firebase Admin の verify_token() で検証。Firebase プロジェクト必須。
- 使い分け: Firebase を使うなら App Check、単体サービスなら直接 reCAPTCHA が一般的。
1. reCAPTCHA v3 とは
reCAPTCHA v3は、Googleが提供する「人間かボットか」を判定するサービスです。従来の v2(「私はロボットではありません」チェックボックスや画像選択)と違い、ユーザーにチャレンジを表示しません。バックグラウンドでユーザーの行動(マウス操作、スクロール、ページ滞在時間など)を分析し、リクエストごとにスコア(0.0~1.0)を返します。
スコアの意味: 1.0 に近いほど人間の可能性が高く、0.0 に近いほどボットの可能性が高いとされます。サイト管理者はこのスコアを閾値と比較して、フォーム送信の許可・拒否、追加認証の要求などを判断します。金融取引やログインなど高リスク操作の保護に適しています。
トークン有効期限: 発行から約2分間。そのため、ページ読み込み時ではなく、ユーザーがアクション(フォーム送信など)を実行するタイミングでトークンを取得する必要があります。なお、siteverify API のドキュメントでは、一部のケースで「5分を超えたトークンは timeout-or-duplicate エラーになる」との記載もあります。
2. 直接 reCAPTCHA の検証フロー(siteverify API)
方式A(直接 reCAPTCHA)では、サーバーが Google の siteverify API(https://www.google.com/recaptcha/api/siteverify)にトークンを送信し、レスポンスの success と score を確認します。リクエストパラメータは secret(シークレットキー)と response(クライアントから受け取ったトークン)です。
レスポンスには success(真偽)、score(0.0~1.0)、action(クライアントで指定したアクション名)、challenge_ts(タイムスタンプ)、error-codes(エラー時)などが含まれます。閾値(例:0.5)以上のスコアであれば人間として扱う、といった判定をサーバー側で実装します。
アクション(action): クライアントで grecaptcha.execute(siteKey, { action: 'page_view' }) のように指定できます。ログイン・購入・コメント投稿など、操作ごとに異なるアクション名を付けると、レポートで分析しやすくなります。レスポンスの action が予期したものと一致するかも確認することが推奨されます。
3. Firebase App Check の検証フロー
方式B(Firebase App Check)では、以下の4ステップで動作します。
- 証明書取得: アプリがプロバイダ(reCAPTCHA v3 等)とやり取りし、デバイス・アプリの真正性の証明書を取得する。
- トークン検証: 証明書が App Check サーバーに送信され、登録パラメータで検証される。
- トークン返却: 有効期限付きの App Check トークンがアプリに返される(TTL は 30分~7日でカスタマイズ可能)。
- トークンキャッシング: Firebase SDK がトークンをキャッシュし、保護されたサービス(Firestore、Cloud Run 等)へのリクエストに自動添付する。
サーバー側では Firebase Admin SDK の app_check.verify_token(token) を呼ぶだけで検証できます。reCAPTCHA のシークレットキーは不要で、Firebase プロジェクトの認証情報(Cloud Run ではデフォルトのサービスアカウント)で検証が行われます。Firestore・Realtime Database・Cloud Storage・Cloud Functions など、複数の Firebase サービスをまとめて保護できます。
4. 二通りの使い方の違い(概要表)
| 項目 | 方式A:直接 reCAPTCHA | 方式B:Firebase App Check |
|---|---|---|
| 検証の仕組み | Google siteverify API にトークンを送信 | Firebase Admin の app_check.verify_token() |
| クライアント | grecaptcha.execute(siteKey) でトークン取得 | Firebase SDK で App Check トークン取得(内部で reCAPTCHA v3 使用) |
| 送るトークン | recaptchaToken(body または ヘッダー) | X-Firebase-AppCheck ヘッダー または appCheckToken |
| サーバーで必要なキー | シークレットキー必須(環境変数) | シークレットキー不要(Firebase 認証情報で検証) |
| 公開キー(サイトキー) | フロントに設定 | フロント+Firebase Console の App Check に登録 |
| 前提条件 | なし | Firebase プロジェクト必須 |
5. キーの役割(サイトキー vs シークレットキー)
| キー | 用途 | 公開/非公開 |
|---|---|---|
| サイトキー(公開キー) | クライアントでトークン取得時に使用。HTML・JS に載せてよい | 公開可 |
| シークレットキー | サーバーで siteverify API 呼び出し時に使用。環境変数で設定 | 非公開(絶対にコードやリポジトリに含めない) |
※ App Check の場合:サーバーは Firebase Admin の verify_token() を使うため、reCAPTCHA のシークレットキーは不要。Firebase のサービスアカウント(Cloud Run ではデフォルト)で検証を行う。
6. 当サイトでの実装例一覧
| サービス | 方式 | 公開キー設定場所 | サーバー検証 |
|---|---|---|---|
| view-tracker(ゲーム閲覧数) | 直接 reCAPTCHA | PAGE_VIEW_TRACKER_RECAPTCHA_SITE_KEY | siteverify API(RECAPTCHA_SECRET_KEY 環境変数) |
| 絵馬アプリ(日本語版) | Firebase App Check | common.js の appCheckSiteKey | Firebase Admin verify_token(APP_CHECK_VERIFY=1) |
| 絵馬アプリ(英語版) | Firebase App Check | firebase-config.js の APP_CHECK_SITE_KEY | Firebase Admin verify_token(APP_CHECK_VERIFY=1) |
7. Cloud Run との連携
| サービス | Cloud Run サービス名 | 環境変数 | 備考 |
|---|---|---|---|
| view-tracker | view-tracker | RECAPTCHA_SECRET_KEY | 未設定なら検証スキップ |
| submit-ema / clap-ema / delete-ema(絵馬) | submit-ema-en, clap-ema-en, delete-ema-en 等 | APP_CHECK_VERIFY=1 | 1 で App Check 検証有効 |
8. どちらを選ぶべきか
| 状況 | 推奨 |
|---|---|
| Firebase(Firestore 等)をすでに使っている | App Check。シークレットキー管理不要で、Firebase サービスをまとめて保護できる |
| Firebase を使っていない単体サービス | 直接 reCAPTCHA。Firebase 導入なしで実装可能 |
9. スコアと閾値の設定
スコアの判定に使う閾値は 0.0~1.0 で設定でき、この値以上のスコアを「人間」として扱います。デフォルト推奨は 0.5 です。閾値を 1.0 に近づけるとボットを強くブロックできますが、正規ユーザーも弾く可能性が高まります。逆に 0.0 に近づけるとボットブロックが弱くなります。まずは 0.5 で運用し、ログを見ながら 0.3~0.7 の範囲で調整するのが一般的です。
なお、一部の情報によると無償プランではスコアが 0.1、0.3、0.7、0.9 の4段階のみ返る場合があるとのこと。有償プランでは 0.0~1.0 の連続値が返る。実際の挙動は公式ドキュメントで確認してください。
10. reCAPTCHA v3 と Enterprise
Google は新規統合では reCAPTCHA Enterprise の使用を推奨しています。Enterprise は v3 と同様のスコアベース検証に加え、アカウント乗っ取り対策や決済詐欺対策などの高度な機能を提供します。料金は月10,000アセスメントまで無料、以降は有料です。既存の v3 ユーザーも、将来的なアップグレード検討の余地があります。
| ティア | 無料枠 | 備考 |
|---|---|---|
| Essentials / Standard | 月10,000まで | v3 で一般的に利用 |
| Enterprise | 月10,000まで | 以降は有料。高度な機能あり。新規推奨 |
11. reCAPTCHA v3 の主な仕様(参考)
- スコア: 0.0(ボットの可能性が高い)~ 1.0(人間の可能性が高い)。閾値は 0.5 を初期値に、0.3~0.7 で調整することが多い。
- トークン有効期限: 約2分。5分を超えると timeout-or-duplicate エラーになる場合も。
- アクション: 英数字とスラッシュで構成。ユーザー固有の値は避ける。レスポンスの action が予期したものか確認することを推奨。
- サイトキー: フロントエンドで使用。HTML・JS に埋め込んでよい(公開可)。
- シークレットキー: サーバーでのみ使用。絶対に公開しない。環境変数で設定。
Artist's Perspective
「絵馬アプリとview-trackerの両方で reCAPTCHA を使っているが、仕組みが違って混乱していた。この記事で二通りの使い方を整理し、自サイトの実装を表にまとめた。今後は App Check と直接 reCAPTCHA の使い分けが明確になった。」
データソース・参考リンク
本記事は以下の情報源を参考にしています。内容の正確性については、必ず元のデータソースをご確認ください。