Cloudflare Turnstileでサイトをbotから守る

Cloudflare Turnstileでサイトをbotから守る

きっかけ

以前にNext.jsでSSRを使わずに画像最適化と多言語化をしてみたという記事で解説したのですが、当サイトでは多言語化を実施することで海外からのアクセスも増えました。
ただ、残念なことにbotに見つかる頻度も上がってしまったようで、お問い合わせフォームにスパムの投稿が増えてしまいました
当サイトはSSGで静的サイトとしてエクスポートしており、また、お問い合わせフォームはサイトからほぼ独立しているため、セキュリティリスク自体は低い方です。
それでもスパムの投稿が増えてしまうのは望ましくないため、対策することにしました。

Cloudflare Turnstile

お問い合わせフォームの認証ではGoogle reCAPTCHAが有名ですが、今回はCloudflare Turnstileを使用します。
Turnstileは、Cloudflareが提供するユーザーフレンドリーでプライバシー重視なCAPTHCAの代替手段です。
現在はベータ版が公開されており、月100万回呼び出しまで無料で使うことができます。
私はCloudflareのサービスを日頃から信頼しているので、今回はこちらを使用してみることにしました。

実装方法

サイトキーとシークレットキーの取得

Cloudflareのダッシュボードでサイトキーシークレットキーを取得しましょう。
メニューバーの「Turnstile」から「サイトを追加」で対象のサイトを追加します。

そうすると、サイトキーシークレットキーが表示されます。
(後でもう一度表示できるのでメモする必要はありません)

フロントエンドの実装

WebサイトにTurnstileのウィジェットを追加します。
今回はNext.js製のサイトに埋め込むので、react-turnstileというライブラリを使用します。

ターミナルでnpm i @marsidev/react-turnstileと入力してインストールし、DocsのExamplesに従ってウィジェットの追加とフォームへの組み込みを行います。
Turnstileコンポーネントをフォームに追加し、そこから得られたtokenをサーバーサイド側にPOSTします。

サーバーサイドの実装

DocsのExamplesCloudflareの公式ドキュメントを参考に実装します。
フロントからPOSTされたtokenとシークレットキーをCloudflare TurnstileのエンドポイントにPOSTします。
結果のsuccessプロパティがtrueならば認証に成功しているので、その後の処理を記述します。

使ってみた感想

概観

無料でサクッと実装できて非常に便利だと感じました。
また、react-turnstileの方も特にトラブルなく機能しました。
reCAPTHA v3のように明示的な認証を行わず裏で認証するようにも設定できるので、認証に失敗したり面倒なパズルを解かされたりするストレスが無く、ユーザー体験も非常によいと思います。

エラーについて

ただ、認証が若干厳しいかなとも感じました。
例えば、フォームを送信したあとにミスに気付いて再度送信したような場合、2回目の投稿がtimeout-or-duplicateとして認証に失敗することがありました。
結果のerror-codesプロパティで上記のエラーが出たら処理を分岐させるなど、何らかの対策は必要かもしれません。
Cloudflareのダッシュボードでは認証の通過率がモニタリングできますので、定期的に確認することが重要だと思います。

目次

Feedback

あなたの一言が大きなはげみとなります!

有効な値を入力してください。
有効な値を入力してください。
有効な値を入力してください。