お問い合わせフォームのスパムを止める

お問い合わせフォームのスパムを止める2 分で読めます

Web サイトのフォーム向け reCAPTCHA の代替

Turnstile や hCaptcha から Proof of Work、CAPTCHA なしまで、フォーム向け reCAPTCHA の代替を比較し、小さく安全な変更で乗り換えます。

Preet SutharIkiform 創業者

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 つの質問で選ぶ

2 つの質問で reCAPTCHA の置き換えを選ぶここからサーバーなし: 静的サイトやビルダーボットは見えないチェックを通り抜けるか?サーバーのコードを動かせるか?自分のウィジェットTurnstile、hCaptcha またはALTCHACAPTCHA なしのままハニーポット、スコア、レート制限フォームをバックエンドに送信バックエンドがキーを検証Turnstile のみ、Ikiform でまたはマネージドの確認キーは一切不要はいはいいいえ2 つの質問で reCAPTCHA の置き換えを選ぶここからサーバーなし: 静的サイトやビルダーボットは見えないチェックを通り抜けるか?サーバーのコードを動かせるか?自分のウィジェットTurnstile、hCaptchaまたは ALTCHACAPTCHAなしのままハニーポット、スコア、レート制限フォームをバックエンドに送信バックエンドがキーを検証Turnstileのみ、Ikiform でまたはマネージドの確認キーは一切不要はいはいいいえ
  1. まず、ボットが目に見えないチェックを通り抜けているかを確認します。そうでなければ、ハニーポット、スコア、レート制限で CAPTCHA なしのままにします。
  2. 通り抜けているなら、サーバーのコードを動かせるかを確認します。動かせるなら、Turnstile、hCaptcha、ALTCHA などのウィジェットを選び、サーバーで検証します。
  3. サーバーがなければ、Turnstile のキーを代わりに検証してくれるバックエンドにフォームを送信するか、キーが不要なマネージドの確認を使います。
ほとんどのお問い合わせフォームは最初の質問で終わります。ウィジェットを追加する前に、スパムの量を測ってください。

reCAPTCHA から Turnstile に乗り換える

2 つはよく似ているので、乗り換えはそれぞれの側で数行の変更で済みます。Cloudflare のダッシュボードで同じホスト名に対して Turnstile のウィジェットを作成し、マークアップとサーバー側の確認を同時に変更します。

部分reCAPTCHA v2Turnstile
スクリプトhttps://www.google.com/recaptcha/api.jshttps://challenges.cloudflare.com/turnstile/v0/api.js
要素<div class="g-recaptcha" data-sitekey><div class="cf-turnstile" data-sitekey>
トークンのフィールドg-recaptcha-responsecf-turnstile-response
検証 URLhttps://www.google.com/recaptcha/api/siteverifyhttps://challenges.cloudflare.com/turnstile/v0/siteverify
検証パラメーターsecret, response, remoteipsecret, 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 のスクリプトを読み込みません。各モードはスパムのドキュメントで説明しています。

同時にホスト型のフォームサービスから移行する場合は、Formspree と Netlify Forms の比較ページで、他に何が変わるかを確認してください。

動作を確認する

  1. 乗り換え後にフォームを送信します。送信は受け付けられ、表示されたのはせいぜいチェックボックスだけです。
  2. トークンなしで curl からエンドポイントに送信します。拒否されれば、サーバーが新しいトークンを確認している証拠です。
  3. ページ内で g-recaptcha と recaptcha/api.js を検索します。何も残っていません。
  4. ダッシュボードで Submissions を開きます。送ったすべてのフィールドを持つ新しい送信データがあります。
  5. 何も届きませんか?ダッシュボードのステータスフィルターを Spam に切り替えてください。スパムにも本物の送信データと同じ成功の応答が返ります。

ハマりどころ

  • ビルダーの設定。 reCAPTCHA の設定を内蔵したサイトビルダーでは、設定がオンの間、すべてのフォームに要素が必要な場合があります。要素を削除する前に設定をオフにしてください。
  • キャッシュされたページ。 古いページがキャッシュに残っている訪問者は、デプロイ後もしばらく g-recaptcha-response を送ってきます。多少の失敗は想定するか、1 日だけ両方のトークンを受け付けてください。
  • レポートの v3 スコア。 ダッシュボードやアラートが reCAPTCHA のスコアを読んでいる場合、乗り換え後は何も出なくなります。更新してください。

よくある質問

手順で詰まったときや、あなたの状況に合うガイドがほしいときはメールでどうぞ: hello@ikiform.com