キャプチャ連携
PrivateStater のキャプチャでフォームをボットとスパムから守る方法です。
PrivateStater のキャプチャは VPN 利用者でもスムーズに使えるよう設計されています (Google の reCAPTCHA では、VPN ユーザーに 10 回以上のチャレンジを求めることがよくあります)。
動作の仕組み
PrivateStater のキャプチャは 3 段階の検証を使います:
- ヘニーポット (Honeypot) - ボットや AI が自動入力する隠しフィールドを検出します。
ヘニーポットは主に低知能の AI ボット向けですが、AI ブラウザを使う利用者もブロックされることがあります。不要なら無効にしてください。Opus 4.6 や 4.7 のような高知能 AI では、ヘニーポットを無視する可能性が高いです。
- パズルチャレンジ - ユーザーがパズル片をドラッグしてはめ込みます
- PoW (Proof of Work) - Argon2id ハッシュを実行し、ボットの攻撃コストを上げます
スクリプト設置
このドキュメント の方法で privatestater.js を設置します。
既に設置済みの場合はこのセクションを飛ばしてください。
ダッシュボードでキャプチャを有効化
- ダッシュボード > ウェブサイト > キャプチャ > 設定 に移動します
- キャプチャを有効化 をオンにします
- 必要に応じてオプションを設定します
設定オプション
| 設定 | 説明 | 既定値 |
|---|---|---|
| 有効 | キャプチャ機能のオン/オフ | 無効 |
| localhost を許可 | localhost でのテストを許可 | 無効 |
| ヘニーポット有効 | AI/ボット検出用の隠しフィールド | 有効 |
| PoW 有効 | パズル後の Proof of Work ステップ | 有効 |
| PoW レベル | Proof of Work の難易度 (low/medium/high) | medium |
PoW 難易度レベル
| レベル | メモリ使用量 | 反復回数 | 目安時間 |
|---|---|---|---|
| low | 4MB | 16 | 約 1 秒 |
| medium | 8MB | 24 | 約 2 秒 |
| high | 16MB | 32 | 約 3 秒 |
難易度が高いほどボット対策は強くなりますが、ユーザーの待ち時間も長くなります。
キャプチャウィジェットの追加
方法 1: 自動初期化 (推奨)
フォーム内の表示位置に data-captcha 属性付きの div を追加します:
<form id="contact-form">
<input type="text" name="name" placeholder="Name">
<input type="email" name="email" placeholder="Email">
<!-- Captcha Widget -->
<div data-captcha="prst"></div>
<button type="submit">Submit</button>
</form>
ページ読み込み時にキャプチャウィジェットが自動表示されます。
方法 2: プログラムから表示
JavaScript で動的にキャプチャを表示できます:
window.PrivateStater.showCaptcha({
container: document.getElementById('captcha-container'),
onSuccess: function(token) {
console.log('Verification successful! Token:', token);
// Send token to your server
},
onError: function(error) {
console.error('Verification failed:', error);
}
});
showCaptcha オプション
| オプション | 型 | 説明 |
|---|---|---|
container |
Element | キャプチャを描画する DOM 要素 (省略時は document.body) |
onSuccess |
Function | 成功時コールバック (トークンを受け取る) |
onError |
Function | 失敗時コールバック (エラーメッセージを受け取る) |
戻り値
showCaptcha は次のメソッドを持つオブジェクトを返します:
const captcha = await window.PrivateStater.showCaptcha({...});
// Remove widget
captcha.destroy();
コールバックの処理
自動初期化 (data-captcha)
グローバルコールバック関数を定義します:
<script>
window.onPrivateStaterCaptchaSuccess = function(token) {
console.log('Captcha verification successful!');
// Add token to form
document.getElementById('captcha-token').value = token;
// Or submit form directly
document.getElementById('contact-form').submit();
};
window.onPrivateStaterCaptchaError = function(error) {
console.error('Captcha error:', error);
alert('Captcha verification failed. Please try again.');
};
</script>
フォーム送信の例
<form id="contact-form" action="/submit" method="POST">
<input type="text" name="name" required>
<input type="email" name="email" required>
<!-- Hidden field to store captcha token -->
<input type="hidden" id="captcha-token" name="captchaToken">
<!-- Captcha Widget -->
<div data-captcha="prst"></div>
<button type="submit">Submit</button>
</form>
<script>
window.onPrivateStaterCaptchaSuccess = function(token) {
document.getElementById('captcha-token').value = token;
};
</script>
サーバーでトークンを検証
クライアントから受け取ったトークンは、必ずサーバー側で検証してください。
API リクエスト
const response = await fetch('https://privatestater.com/api/captcha/validate', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
websiteId: 'YOUR_SITE_ID',
verifyToken: captchaToken
})
});
const result = await response.json();
if (result.success) {
// Captcha verification successful, proceed with form processing
} else {
// Verification failed
console.error('Captcha verification failed:', result.error);
}
Node.js/Express の例
app.post('/submit', async (req, res) => {
const { name, email, captchaToken } = req.body;
// Verify captcha token
const captchaResponse = await fetch('https://privatestater.com/api/captcha/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
websiteId: process.env.PRST_SITE_ID,
verifyToken: captchaToken
})
});
const captchaResult = await captchaResponse.json();
if (!captchaResult.success) {
return res.status(400).json({ error: 'Captcha verification failed' });
}
// Captcha verification successful, proceed with form processing
// ...
res.json({ success: true });
});
検証 API のレスポンス
成功時:
{
"success": true
}
失敗時:
{
"success": false,
"error": "token_invalid_or_expired"
}
重要な注意
- トークンは 1 回限り です。検証後は直ちに破棄されます。
- トークンは 5 分で期限切れ になります。
- 検証は サーバー側 で行ってください。
キャプチャ統計
ダッシュボードでキャプチャの利用統計を確認できます:
| 統計 | 説明 |
|---|---|
| 試行 | 作成されたキャプチャチャレンジ数 |
| 成功 | 完了した検証数 |
| ヘニーポット失敗 | ヘニーポットで捕捉したボット数 |
| パズル失敗 | パズル不一致の回数 |
| PoW 失敗 | Proof of Work 失敗の回数 |
| タイムアウト | 5 分以内に完了しなかった回数 |
| 成功率 | 成功 / 試行の比率 |
スタイル
キャプチャウィジェットは Shadow DOM で隔離されているため、外部 CSS の影響を受けません。prefers-color-scheme を検出し、ダーク/ライトに自動対応します。
多言語対応
キャプチャウィジェットはブラウザの言語に応じて韓国語または英語で表示されます。
追加の言語が必要な場合は hello@privatestater.com までご連絡ください。対応を追加します。
トラブルシューティング
キャプチャウィジェットが表示されない
- ダッシュボードでキャプチャが 有効 か確認します
- スクリプトが正しく設置されているか確認します
- コンソールのエラーを確認します
localhost で動作しない
ダッシュボードで localhost を許可 を有効にしてください。
トークン検証に失敗する
- トークンの期限 (有効 5 分) を確認します
- トークンが既に使われていないか確認します (1 回限り)
websiteIdが正しいか確認します
エラーコード
| エラー | 原因 |
|---|---|
token_invalid_or_expired |
トークン期限切れまたは使用済み |
website_id_mismatch |
トークンと websiteId が一致しない |
captcha_not_enabled |
キャプチャが有効になっていない |
host_mismatch |
リクエスト Origin が登録ドメインと一致しない |