サイトにウィジェットを追加する
前のレッスン で BananaSeed の公開鍵を手に入れました。次は React の問い合わせフォームにウィジェットを置き、本物の訪問者がそれをクリアしたことをダッシュボードが確認するのを見届け、そしてそれを本物の保護に変える 1 つのサーバー呼び出しを追加します。
最後にあなたが手にするもの
- 問い合わせフォームの上のウィジェットが、ブラウザで訪問者を検証している状態。
- ダッシュボードがそれらの検証を表示している状態。
- 有効なトークンを持たないあらゆる送信を、Node バックエンドが捨てている状態。
1. React フォームにウィジェットを追加する
パッケージをインストールします。これは <caputchin-widget> 要素(と、次のレッスン用の <caputchin-game> 要素)を登録します:
npm install @caputchin/widget起動時に一度、たとえばアプリのエントリーポイント(main.jsx)でインポートします:
import "@caputchin/widget";では、ウィジェットを BananaSeed の問い合わせフォームに置きましょう。チェックボックスがクリアされると、ウィジェットはフォームに隠しの caputchin-token フィールドを追加するので、送信時にあなた自身のフィールドとまったく同じように読み取れます。cpt_pub_... をあなたの公開鍵に置き換えてください:
export function ContactForm() {
async function handleSubmit(e) {
e.preventDefault();
const data = new FormData(e.currentTarget);
await fetch("/api/contact", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
email: data.get("email"),
message: data.get("message"),
token: data.get("caputchin-token"),
}),
});
}
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" required />
<textarea name="message" required />
<caputchin-widget sitekey="cpt_pub_..." />
<button type="submit">Send</button>
</form>
);
}ビルド手順のない素の HTML ページ上、あるいはネイティブのモバイルアプリの中で使う場合は?script タグ(CDN)連携 と モバイルアプリガイド を参照してください。
2. 検証されるのを見る
アプリを実行して問い合わせフォームを開きます。Caputchin のチェックボックスが現れ、クリックも要らず、ひとりでに完了します。フォームをまだ送信する必要すらありません。それはすでに本物の検証であり、Caputchin に届いています。
3. ダッシュボードで確認する
ダッシュボードに戻り、チームを開いてサイトキーへ入ります。その統計はファネルを示します:セッション開始、クライアント側で完了、サーバー側で検証済み、そして 脅威をブロック。ページを更新すると、セッション開始 と クライアント側で完了 が両方とも少なくとも 1 になります。それがあなたの訪問です。ウィジェットが読み込まれ(開始)、チャレンジがブラウザで解かれた(クライアント側で完了)ので、バックエンドはまったく関与していません。
サーバー側で検証済み はまだ 0 です。あなたのサーバー上のものがまだトークンを 1 つも確認していないからです。そのギャップが次のステップです。
ウィジェットはライブで、ダッシュボードはバックエンドのコードを 1 行も書く前から、すでに本物の検証を記録しています。🎉
4. バックエンドでトークンを検証する
クライアント側で完了は、訪問者がチャレンジをクリアしたことを意味しますが、サーバーがトークンを確認するまで、あなたのフォームは保護されていません。ボットはウィジェットを完全に無視して、エンドポイントへ直接 POST できます。だからこそ、バックエンドはリクエストを信頼する前に、すべてのトークンを Caputchin で確認します。あなたのシークレット(cpt_sec_...)は環境変数に住み、決してブラウザにはありません:
import express from "express";
const app = express();
app.use(express.json());
app.post("/api/contact", async (req, res) => {
const { email, message, token } = req.body;
const verdict = await fetch("https://caputchin.com/api/v1/siteverify", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
secret: process.env.CAPUTCHIN_SECRET,
response: token,
}),
}).then((r) => r.json());
if (!verdict.success) {
return res.status(400).json({ error: "Could not verify you are human." });
}
// Verified. Handle the real message: store it, email it, whatever you do.
res.json({ ok: true });
});
app.listen(3001);その verdict.success の確認こそが要点です。/api/contact へ直接ポストするボットはトークンを持たず、success は false で返り、メッセージはあなたが触れる前に捨てられます。
バックエンドがない?問題ありません。ホスト型認証 をオンにすれば、Caputchin がこの確認をあなたの代わりに実行し、検証済みの送信だけを webhook か受信トレイへ転送します。
5. サーバーの確認を検証する
エンドポイントが検証するようになった今、もう一度だけ問い合わせフォームを送信します。サイトキーの統計に戻って更新すると:サーバー側で検証済み も今や少なくとも 1 になり、開始とクライアント側で完了の隣に並びます。ブラウザからサーバーまで、ファネル全体が説明できます。
そのファネルを逆向きに読む方法(カウント間のギャップが、訪問者の離脱や連携ミスについて何を語るか)については、統計とセッション を参照してください。
問い合わせフォームは今や本当に保護されています。すべての送信がサーバーで確認され、トークンを持たないボットは追い返されます。🎉
たった今起きたこと
| ステップ | 場所 | 結果 |
|---|---|---|
フォームの <caputchin-widget> | React | チェックボックスがマウント時に検証し、一度きりの caputchin-token フィールドを追加します。 |
| ページを開く | ブラウザ | 開始とクライアント側で完了が進み、バックエンドは要りません。 |
シークレット付きの /siteverify | Node から Caputchin | success: true がリクエストを通します。トークンがなければ捨てられ、サーバー側で検証済みが伸びます。 |
次へ
チェックボックスが動きます。次は楽しいところ:それを本物の遊べるゲームに、バックエンドを一切変えずに差し替えます。
マーケットプレイスからゲームを追加する へ進みましょう。