お問い合わせフォームのスパムを止める2 分で読めます
Web サイトのフォーム向け reCAPTCHA の代替
Turnstile や hCaptcha から Proof of Work、CAPTCHA なしまで、フォーム向け reCAPTCHA の代替を比較し、小さく安全な変更で乗り換えます。
reCAPTCHA に最も近い置き換えは Cloudflare Turnstile です。ほとんど目に見えず、サイトキーとシークレットキーという同じ構成で、サーバー側の確認も同じパラメーターを受け取ります。hCaptcha は Google 以外から画像チャレンジを提供したいサイトに向いており、ALTCHA などの Proof of Work のツールは第三者をまったく介さずに動きます。多くのお問い合わせフォームでは、ハニーポット、内容のスコア、レート制限があれば CAPTCHA は不要です。
reCAPTCHA から移行する理由
reCAPTCHA は今も動きます。置き換える理由はたいてい、訪問者とあなたにかかるコストです。バージョン 2 は一部の訪問者に画像パズルを表示し、スマートフォンでは時間がかかり、スクリーンリーダーの利用者には難しいものです。バージョン 3 は目に見えませんが、返すのはスコアで、しきい値は自分で決める必要があり、代わりに出せるチャレンジもありません。また、reCAPTCHA は現在 Google Cloud の製品です。Google の課金ドキュメントには、月 10,000 件の評価までの無料枠と、それを超える有料の階層が記載されています。
ページ上のサードパーティのスクリプトを減らしたいチームもあります。それがプライバシー上の義務に関わるかどうかは、自身の法務レビューで判断すべき問題です。このページではツールの仕組みを比較するだけです。
代替手段の比較
| 選択肢 | 訪問者に見えるもの | 検証する者 | 知っておくこと |
|---|---|---|---|
| reCAPTCHA v2 | チェックボックス、ときどき画像パズル | 自分のサーバーが Google と | なじみがある。パズルが主な不満点 |
| reCAPTCHA v3 | 何もなし | 自分のサーバーが Google と | 0.0 から 1.0 のスコアを返す。しきい値を選び、グレーゾーンを自分で扱う |
| Cloudflare Turnstile | たいてい何もなし、ときどきチェックボックス | 自分のサーバーが Cloudflare と | 画像パズルなし。ウィジェット 20 個まで無料 |
| hCaptcha | チェックボックス、ときどき画像パズル | 自分のサーバーが hCaptcha と | 形は reCAPTCHA v2 に近く、提供元が違う。無料の Basic プランと、有料の Pro と Enterprise プラン |
| Friendly Captcha | バックグラウンドでパズルを解く小さなウィジェット | 自分のサーバーが Friendly Captcha と | トラッキングのシグナルではなく Proof of Work。小規模な非商用サイトは無料、それ以外は有料プラン |
| ALTCHA | バックグラウンドでパズルを解く小さなウィジェット | 自分のサーバーだけ | オープンソースでセルフホストなので第三者なし。運用と保守は自分で行う |
| No captcha | 何もなし | 自分のサーバー | ハニーポット、署名付きの時間計測、内容のスコア、レート制限。ほとんどのボットを止めるが、すべてではない |
最後のもの以外は、どれもサーバー側の確認に依存します。ボットはページを読み込まずにエンドポイントに送信できるので、ウィジェットだけでは何も止められません。
それぞれの選択肢が人に求めるもの
どの選択肢も、それを最も使いにくいと感じる訪問者を基準に判断してください。画像パズルはスマートフォンでは時間がかかり、目がよく見えない人には難しいか不可能です。音声の代替は助けになる人もいれば、いら立つ人もいます。Turnstile の通常モード、reCAPTCHA v3、Proof of Work のウィジェットのような目に見えない確認は、ほとんどの訪問者に何も求めませんが、プライバシー重視のブラウザー、制限の厳しいネットワーク、古い端末を使う人には失敗することがあります。そうなったとき、その人には先に進む手段が必要です。表示されるチェックボックス、わかりやすいメッセージ、代わりに送れるメールアドレスなどです。何も言わずに失敗するフォームは、まさにあなたが知ることのないメッセージを失います。
2 つの質問で選ぶ
- まず、ボットが目に見えないチェックを通り抜けているかを確認します。そうでなければ、ハニーポット、スコア、レート制限で CAPTCHA なしのままにします。
- 通り抜けているなら、サーバーのコードを動かせるかを確認します。動かせるなら、Turnstile、hCaptcha、ALTCHA などのウィジェットを選び、サーバーで検証します。
- サーバーがなければ、Turnstile のキーを代わりに検証してくれるバックエンドにフォームを送信するか、キーが不要なマネージドの確認を使います。
reCAPTCHA から Turnstile に乗り換える
2 つはよく似ているので、乗り換えはそれぞれの側で数行の変更で済みます。Cloudflare のダッシュボードで同じホスト名に対して Turnstile のウィジェットを作成し、マークアップとサーバー側の確認を同時に変更します。
| 部分 | reCAPTCHA v2 | Turnstile |
|---|---|---|
| スクリプト | https://www.google.com/recaptcha/api.js | https://challenges.cloudflare.com/turnstile/v0/api.js |
| 要素 | <div class="g-recaptcha" data-sitekey> | <div class="cf-turnstile" data-sitekey> |
| トークンのフィールド | g-recaptcha-response | cf-turnstile-response |
| 検証 URL | https://www.google.com/recaptcha/api/siteverify | https://challenges.cloudflare.com/turnstile/v0/siteverify |
| 検証パラメーター | secret, response, remoteip | secret, response, remoteip, idempotency_key |
<form action="/api/contact" method="POST">
<input name="email" type="email" required />
<textarea name="message" required></textarea>
<div class="g-recaptcha" data-sitekey="RECAPTCHA_SITE_KEY"></div>
<button>Send</button>
</form>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>const form = await request.formData();
const body = new URLSearchParams({
secret: process.env.RECAPTCHA_SECRET_KEY!,
response: String(form.get("g-recaptcha-response") ?? ""),
});
const check = await fetch("https://www.google.com/recaptcha/api/siteverify", { method: "POST", body });
const { success } = (await check.json()) as { success: boolean };- これは
siteverifyで検証する従来の reCAPTCHA キーの場合です。Google Cloud で作成したキーは、代わりに reCAPTCHA Enterprise の assessments API で確認します。Turnstile 側は同じです。 - v3 を使っていた場合は、スコアのしきい値を削除してください。Turnstile は合格か不合格かを返すので、代わりに応答の
actionを確認します。 - Content Security Policy を更新します。
script-srcとframe-srcでhttps://challenges.cloudflare.comを許可し、Google の項目は使わなくなったら削除します。 - マークアップとサーバーの変更は 1 回のデプロイで出してください。新しいウィジェットのページが、まだ
g-recaptcha-responseを期待するサーバーに送信すると、すべての送信が失敗します。
reCAPTCHA を Ikiform に置き換える
フォームの送信先が Ikiform なら、reCAPTCHA のウィジェットは完全に削除してください。Ikiform は reCAPTCHA や hCaptcha のトークンを検証しません。残った g-recaptcha-response の値は余分なフィールドとして届くか、フォームのフィールドを定義していれば未知のフィールドとして 422 validation_failed で失敗します。そのうえで、代わりに何を使うかを選びます:
- 追加なし。 ハニーポット、内容のスコア、レート制限はすべてのフォームで動きます。多くのお問い合わせフォームにはこれで十分です。
- Spam check を Ikiform に設定。 Ikiform が実行する Cloudflare Turnstile で、アカウントもキーも不要です。プレーンな HTML の送信には短い確認ページが表示され、
fetchのコードでは@ikiform/sdkのchallenge()を呼びます。 - 自分の Turnstile キー。 自分のウィジェットをページに残し、キーをフォームの設定に貼り付けると、Ikiform がトークンを検証します。
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="POST">
<input name="email" type="email" required />
<textarea name="message" required></textarea>
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button>Send</button>
</form>このフォームにはウィジェットがまったくありません。Spam check を Ikiform にすると、人間確認は送信後に ikiform.com で行われるので、ページは CAPTCHA のスクリプトを読み込みません。各モードはスパムのドキュメントで説明しています。
動作を確認する
- 乗り換え後にフォームを送信します。送信は受け付けられ、表示されたのはせいぜいチェックボックスだけです。
- トークンなしで curl からエンドポイントに送信します。拒否されれば、サーバーが新しいトークンを確認している証拠です。
- ページ内で
g-recaptchaとrecaptcha/api.jsを検索します。何も残っていません。 - ダッシュボードで Submissions を開きます。送ったすべてのフィールドを持つ新しい送信データがあります。
- 何も届きませんか?ダッシュボードのステータスフィルターを Spam に切り替えてください。スパムにも本物の送信データと同じ成功の応答が返ります。
ハマりどころ
- ビルダーの設定。 reCAPTCHA の設定を内蔵したサイトビルダーでは、設定がオンの間、すべてのフォームに要素が必要な場合があります。要素を削除する前に設定をオフにしてください。
- キャッシュされたページ。 古いページがキャッシュに残っている訪問者は、デプロイ後もしばらく
g-recaptcha-responseを送ってきます。多少の失敗は想定するか、1 日だけ両方のトークンを受け付けてください。 - レポートの v3 スコア。 ダッシュボードやアラートが reCAPTCHA のスコアを読んでいる場合、乗り換え後は何も出なくなります。更新してください。
よくある質問
ほとんどのフォームでは Cloudflare Turnstile です。たいてい目に見えず、小規模なら無料で、同じ secret と response のパラメーターで検証します。第三者を一切介したくないなら、ALTCHA のようなセルフホストの Proof of Work ツールが使えます。ハニーポット、スコア、レート制限がそろえば、CAPTCHA が要らないお問い合わせフォームも多くあります。
Google の課金ドキュメントには、月 10,000 件の評価までの無料枠と、それを超える有料の階層が記載されています。計画を立てる前に、Google の最新の料金を確認してください。
いいえ。Ikiform が検証するのは Cloudflare Turnstile だけで、Ikiform 自身のマネージドの確認か、あなたの Turnstile キーのどちらかです。Ikiform に送信するフォームからは、他の CAPTCHA のウィジェットを削除してください。
たいていは大変ではありません。スクリプトの URL、要素のクラス、トークンのフィールド名、検証 URL を変え、secret と response のパラメーターはそのまま使います。ページとサーバーの変更は一緒にデプロイしてください。
手順で詰まったときや、あなたの状況に合うガイドがほしいときはメールでどうぞ: hello@ikiform.com