Auth0 は、パスワードまたはパスワードレスのコードで新規登録するユーザー(Database 接続または Passwordless 接続)を作成する前に Action を実行します。この Action から Bot Protection を呼び出し、新規登録を拒否できます。新規登録ページは Auth0 のドメイン上にある Auth0 のページなので、Action には _kz Cookie が届きません。判定は IP と User-Agent にもとづいて行われます。
タグ
訪問者が新規登録の前に訪れるページや、ログイン・支払いを行うページなど、自社のページにタグを置いてください。そうした判定には token が付きます。
<script src="https://korzen.dev/v1/tag.js" data-site-key="YOUR_SITE_KEY" async></script>
呼び出し
Action です。Auth0 が Action に与える時間は合計 20 秒です。呼び出しはお客様のタイムアウトに従い、それ以外の場合はすべて新規登録を通します。
// Auth0 Dashboard: Actions, Triggers, pre-user-registration; a new Action. // Add the secret KORZEN_API_KEY to the Action. exports.onExecutePreUserRegistration = async (event, api) => { let d = null; try { const res = await fetch("https://korzen.dev/v1/decide", { method: "POST", headers: { Authorization: `Bearer ${event.secrets.KORZEN_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ ip: event.request.ip, user_agent: event.request.user_agent, ja4: event.security_context?.ja4 || undefined, // behind Cloudflare only: left out without it headers: { "accept-language": event.request.language }, path: "/signup", method: "POST", }), signal: AbortSignal.timeout(200), }); if (res.ok) d = await res.json(); } catch {} // fail open if (d?.action === "block") { api.access.deny("korzen_block", "We could not create your account."); return; } // "challenge": Auth0's own CAPTCHA or MFA, if your plan has them if (d?.request_id) api.user.setAppMetadata("korzen_request_id", d.request_id); };
Auth0 が Action に渡すのはブラウザーの言語と User-Agent だけで、リクエストのほかのヘッダーは渡さないため、この呼び出しが送るのは accept-language だけです。同じブラウザービルドが同じ値で送るヘッダーは、Bot Protection がサーバーからの呼び出しで読むものですが、ここにはありません。
トラフィックが Cloudflare を通るテナント(Auth0 の Enterprise プラン)では、イベントに security_context.ja4 もあります。これは訪問者と Auth0 のエッジとの TLS ハンドシェイクの JA4 で、自社サーバーの前の Cloudflare から Bot Protection が読むのと同じ形式です。呼び出しは、値があれば ja4 として送り、なければ省きます。
訪問者の IP
event.request.ip は Auth0 に到達したアドレスで、すでに訪問者のものになっています。設定は不要です。自前のプロキシの背後にカスタムドメインを置いている場合は、訪問者の IP について Auth0 のカスタムドメイン設定を確認してください。
Auth0 からの判定にはタグの token が付きません。ほかのページでタグが検出された後は、token がないと score が少し上がります(no_token)が、それだけで bot になることはありません。
アクションを適用する
読むのは action だけです。block の場合は、その操作がほかの理由で失敗したときと同じエラーを返し、bot に何も悟らせないようにします。challenge の場合は、すでにある確認手段(CAPTCHA、メールや電話の確認コード)を使います。何もなければそのまま続けます。アカウントは monitor mode で始まり、その間 action は常に allow です。block mode をオンにするまで、訪問者にとっては何も変わりません。
request_id を保存する
すべての応答には request_id が含まれます。操作で作成されたもの(アカウントや注文)のカラムに保存するか、その ID と一緒にログに残してください。お問い合わせの際にその判定を特定でき、後からどの応答が偽アカウントを通したのかを調べられます。
手元のマシンでテストする
開発用のテナントを使います。Action エディターの Test でサンプルイベントを使って実行し、次にログインページから新規登録すると、判定が dashboard の判定ページに /signup で表示されます。fail-open は、シークレット KORZEN_API_KEY に誤った値を設定して確認します。新規登録はそのまま完了します。
よくある間違い
- ソーシャルログインによる新規登録。Google や GitHub などでは pre-user-registration トリガーが実行されません。post-login Action を使えば、初回ログイン時に Bot Protection に問い合わせられます。
- ブラウザーから
/v1/decideを呼び出す。API key がすべての訪問者に渡ってしまいます。呼び出しはサーバーで行ってください。 - タイムアウトがない、またはエラーで新規登録が止まる。
200以外の応答や、時間内に応答がない場合は、訪問者を通すという意味です。