メインコンテンツに移動

ベストプラクティス

年齢確認のベストプラクティス

確認失敗の処理

アクセス年齢確認を実装する際、開発者は確認結果のfailureReasonフィールドをチェックして、失敗を適切に処理する必要があります:

  • 不正活動検出: 確認が失敗し、failureReasonfraudulent-activity-detectedの場合、そのユーザーの追加確認試行を許可しないでください。
  • その他の失敗理由: その他の失敗理由(age-criteria-not-metmax-attempts-exceededなど)については、乱用を防ぎながら正当な再試行を許可するためにレート制限を実装してください。24時間あたり最大3回の確認試行を許可してください。これにより、ユーザーが確認システムを回避しようとする繰り返し試行を防ぎながら、正当なユーザーに合理的な再試行機会を提供します

セキュリティ推奨事項

バックエンド専用API呼び出し

重要:すべてのウィジェットURL生成エンドポイントは、バックエンドサーバーからのみ呼び出される必要があります。クライアントサイドコードから直接呼び出してはいけません。 k-ID APIキーは保護する必要がある秘密の認証情報です:

  • シークレットマネージャーを使用してAPIキーを安全に保存
  • フロントエンドJavaScript、モバイルアプリコード、またはクライアント向けコードでAPIキーを公開しない
  • クライアントデバイスやクライアントサイドストレージにAPIキーを保存しない

ターゲットオリジンの設定

コンプライアンススタジオでターゲットオリジンを設定して、どのドメインがウィジェットを埋め込みできるかを制御します。この設定はframe-ancestorsディレクティブを制御し、クリックジャッキング攻撃から保護します。

設定オプション:

  • 特定のドメイン: 本番使用のための正確なドメインを設定(例:https://yourgame.com
  • ワイルドカードサブドメイン: サブドメイン用のワイルドカードパターンを使用(例:https://*.yourgame.com
  • 無制限: 無制限の埋め込みのために空のままにするか*に設定(本番環境では推奨されません)

セキュリティ上の利点: ターゲットオリジンは、攻撃者が悪意のあるサイトの透明なiframeに確認フローを埋め込み、他のコンテンツをオーバーレイしてユーザーを確認要素を誤ってクリックするように騙すことを防ぎます。

実装上の注意:

  • 各環境(テスト/ライブ)に個別のターゲットオリジンを設定
  • 本番環境に移行する前に、すべての本番エンドポイントのターゲットオリジンが適切に設定されていることを確認してください。
  • ワイルドカードを使用しない限り、各サブドメインには独自のエントリが必要
  • ターゲットオリジン設定に関係なく、特定のk-IDページのみがiframeに埋め込み可能(確認ページ、ウィジェット、VPCフロー)
  • その他のすべてのk-IDページ(ファミリー管理、アカウント設定)は常にiframe埋め込みからブロックされます

これはオプションですが推奨されるセキュリティ対策です。リスク許容度を評価し、セキュリティ要件に基づいてターゲットオリジン制限を実装するかどうかを決定することをお勧めします。

iframe権限

iframeのallow属性に必要な権限を常に含めてください:

<iframe 
src="WIDGET_URL"
allow="camera;autoplay;payment;publickey-credentials-get;publickey-credentials-create"
width="100%"
height="600"
></iframe>

権限の詳細:

  • camera - 顔年齢推定に必要
  • autoplay - 顔年齢推定で使用(オプション、コンソール警告を防ぐ)
  • payment - クレジットカード確認用(オプション、ブラウザ支払いAPIを有効にする)
  • publickey-credentials-get/create - 年齢キー確認に必要

オリジン検証

受信メッセージのオリジンを常に検証してください:

window.addEventListener('message', (event) => {
// 環境に基づいてオリジンを検証
const validOrigins = [
'https://family.k-id.com', // ライブ環境
'https://family.test.k-id.com' // テスト環境
];

if (!validOrigins.includes(event.origin)) {
return; // 未承認のオリジンからのメッセージを無視
}

// イベントを処理
handleWidgetEvent(event.data);
});