CAPTCHAの代替となるCloudflare Turnstileが便利すぎる
https://2.bp.blogspot.com/-H2eLSLfzvpA/XGjx1UapC6I/AAAAAAABRcA/5Xdh-W7tqk8X1YONndv2B1ykhJ6BRS1bgCLcBGAs/s800/ai_computer_sousa_robot.png
【前提】
ボットによる操作か人間による操作なのかをテストする際に真っ先に浮かぶのがCAPTCHA機能であり、ベンダーが提供するサービスとしては、reCAPTCHAやhCaptchaなどが挙げられます。これらの機能はユーザーに画像のチェック等の操作をすることでユーザーが人間なのかロボットなのかを判別することができます。一方で、これらのユーザーアクションはユーザー体験を損ねてしまう可能性があるため、セキュアなアプリケーションを担保するためのトレードオフとなったりします。ではユーザー体験を損ねず、アプリケーションのセキュリティを担保することはできないのでしょうか?
【結論】
Cloudflare Turnstileを活用しましょう。Cloudflare TurnstileはCAPTHCHAの代替となっており、ユーザーに画像のチェック等を強制することはありません。2023年4月現在2023年4月現在、reCAPTCHA v3も同様な機能を提供していますが、月に1,000,000回以上の利用に際し料金が発生しますが、Cloudflare Turnstileはアカウントさえ作成すれば無料で利用することができます。
【認証の流れと実装】
Cloudflare Turnstileによる認証の流れは以下のとおりです。
1. クライアントサイドでボットかどうかを判別するチャレンジを実行し、実行結果を内包するトークンをchallenges.clloudflare.comから取得
2. 取得したトークンを自サービスのサーバーサイドに投げる
3. 2のトークン、Cloudflare Turnstileが提供するsitekeyおよびsecret keyをchallenges.clloudflare.comのSiteverify APIに投げることで認証を実施
実装方法についてはクライアントサイドおよびサーバーサイドの説明がされているので、この通りに実装していけば難しいことはそこまでないです。また、ドキュメントでは各ベンダーが提供しているCAPTCHAからCloudFlare Turnstileの移行作業についても説明しています。
サーバーサイドの実装で少し気になるのは、FormDataを利用して、サーバーサイドのfetchを実施しているところですが、その場合はform-dataのパッケージが必要になります。そこまでしなくてもNode.js < 18の場合はnode-fetch、Node.js > 18の場合はfetch APIを活用し、JSON.stringifyでシリアライズした上でペイロードを生成するとよいでしょう。
下記に擬似コードを記載します。
code: test.ts
import fetch from 'node-fetch' // Node.js < 18のとき
...
const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'
const result await fetch(url, Json.stringify(
{
secret,
response,
ip,
})
)
...
【余談】
このクオリティを無料で提供してるCloudflareは本当にすごいです…。