カスタム年齢ゲート
このガイドでは、事前に構築されたウィジェットを使用せずに、k-ID API を直接使用してカスタム年齢ゲートを実装する方法を説明します。このアプローチにより、k-ID がコンプライアンスロジックを処理する間、ユーザーインターフェースを完全にコントロールできます。
このガイドでは、Compliance Studio ですべての権限を必須として設定するシンプルな統合パターンを紹介します。この設定では、セッションが作成されると(直接または保護者の同意後に)、すべての機能がすぐに利用可能になります。セッションアップグレードフローは必要ありません。
カスタム年齢ゲートとは?
カスタム年齢ゲートは、お客様が構築・管理する年齢確認インターフェースであり、k-ID の API がバックエンドでコンプライアンスロジックを処理します。このアプローチは以下のような場合に最適です:
- 完全な UI コントロール:ブランドとユーザー体験に合わせた年齢ゲートをデザイン
- プラットフォーム統合:モバイルアプリやゲームエンジン向けのネイティブ体験を構築
- カスタムワークフロー:より大きなオンボーディングフローの一部として年齢確認を実装
前提条件
始める前に、以下が必要です:
- k-ID プロダクト:k-ID Compliance Studioでプロダクトを作成・設定
- 必須権限の設定:プロダクトの権限設定ですべての権限を「必須」として設定
- API キー:Compliance Studioのプロダクトの開発者設定ページから API キーを生成
- Webhook エンドポイント(推奨):チャレンジおよびセッションイベントを受信するためのセキュアな HTTPS エンドポイントを設定。詳細はWebhooksを参照。
ステップ 1:年齢ゲート要件を取得
年齢ゲートを表示する前に、/age-gate/get-requirementsを呼び出して、ユーザーの管轄区域に基づいて表示すべき内容を決定します。
実装では、API キーがクライアント側のコードに公開されないよう、すべての API 呼び出しはサーバー間で行う必要があります。
リクエスト例
GET /api/v1/age-gate/get-requirements?jurisdiction=US-CA
Authorization: Bearer your-api-key
レスポンス例
{
"shouldDisplay": true,
"ageAssuranceRequired": false,
"digitalConsentAge": 13,
"civilAge": 18,
"minimumAge": 0,
"approvedAgeCollectionMethods": [
"date-of-birth",
"age-slider",
"platform-account"
]
}
レスポンスフィールド
| フィールド | 説明 |
|---|---|
shouldDisplay | 年齢ゲートを表示すべきかどうか |
ageAssuranceRequired | この管轄区域で年齢確認が必要かどうか |
digitalConsentAge | デジタル同意の最低年齢(これ未満のユーザーは保護者の同意が必要) |
civilAge | ユーザーが法的に成人とみなされる年齢 |
minimumAge | プロダクトにアクセスするための最低年齢(Compliance Studio で設定) |
approvedAgeCollectionMethods | この管轄区域で許可されている年齢収集方法 |
shouldDisplayがfalseの場合、年齢ゲートをスキップし、/age-gate/get-default-permissionsを呼び出して、その管轄区域のデフォルトセッション権限を取得します。
ステップ 2:年齢ゲート UI を構築
レスポンスに基づいて、承認された収集方法を使用して年齢ゲートインターフェースを構築します:
date-of-birth:完全な生年月日入力(YYYY-MM-DD)age-slider:年齢範囲またはスライダー選択platform-account:既存のプラットフォームアカウントの年齢データを使用
年齢スライダーの動作、日付ピッカーの要件、アクセシビリティに関する考慮事項などの詳細な設計推奨事項については、UXガイドラインを参照してください。
年齢ゲート UI の例
<div id="age-gate">
<h2>生年月日を入力してください</h2>
<form id="age-gate-form">
<label for="dob">生年月日</label>
<input type="date" id="dob" name="dob" required />
<button type="submit">続行</button>
</form>
</div>
ステップ 3:API で年齢を確認
ユーザーが年齢を送信したら、収集した年齢情報と管轄区域を指定して/age-gate/checkを呼び出します。使用した年齢収集方法に応じて、dateOfBirthまたはageのいずれかを渡すことができます。
生年月日を使用したリクエスト例
日付ピッカーを使用して完全な生年月日を収集した場合:
POST /api/v1/age-gate/check
Content-Type: application/json
Authorization: Bearer your-api-key
{
"jurisdiction": "US-CA",
"dateOfBirth": "2015-04-15"
}
年齢を使用したリクエスト例
年齢スライダーを使用してユーザーの年齢を収集した場合:
POST /api/v1/age-gate/check
Content-Type: application/json
Authorization: Bearer your-api-key
{
"jurisdiction": "US-CA",
"age": 9
}
可能なレスポンス
API は 3 つのステータスのいずれかを返します:
PASS: ユーザーは続行可能
ユーザーの年齢により即座にアクセスが許可されます。すべての権限を持つセッションが作成されます。
{
"status": "PASS",
"session": {
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"ageStatus": "LEGAL_ADULT",
"dateOfBirth": "2005-04-15",
"jurisdiction": "US-CA",
"permissions": [...],
"status": "ACTIVE"
}
}
アクション:sessionIdを保存し、ユーザーが続行できるようにします。
PROHIBITED: ユーザーはブロック
ユーザーの年齢がプロダクトに設定された最低年齢を下回っています。
{
"status": "PROHIBITED"
}
アクション:年齢に適したメッセージを表示し、アクセスを防止します。
CHALLENGE: 保護者の同意が必要
ユーザーの年齢により検証可能な保護者の同意(VPC)が必要です。信頼できる大人が承認するためのチャレンジが作成されます。
{
"status": "CHALLENGE",
"challenge": {
"challengeId": "683409f1-2930-4132-89ad-827462eed9af",
"oneTimePassword": "PP5BUS",
"type": "CHALLENGE_PARENTAL_CONSENT",
"url": "https://family.k-id.com/authorize?otp=PP5BUS"
}
}
アクション:challengeIdを保存し、信頼できる大人のチャレンジ画面を表示します(ステップ 4 を参照)。
ステップ 4:信頼できる大人のチャレンジ画面を構築
CHALLENGEレスポンスを受け取ったら、ユーザーが同意を求めて信頼できる大人に連絡できる画面を表示します。チャレンジレスポンスには必要なものがすべて含まれています。
信頼できる大人の同意フローの詳細な設計推奨事項(レイアウト例や実装のヒントを含む)については、UXガイドラインの保護者同意を参照してください。
チャレンジ画面のオプション
チャレンジ画面では、信頼できる大人が同意を完了するための 3 つのオプションを提供する必要があります:
オプション 1:メール通知
ユーザーが信頼できる大人のメールアドレスを入力できるようにします。送信されたら、/challenge/send-emailを呼び出して同意リクエストメールを送信します。
POST /api/v1/challenge/send-email
Content-Type: application/json
Authorization: Bearer your-api-key
{
"challengeId": "683409f1-2930-4132-89ad-827462eed9af",
"email": "parent@example.com"
}
オプション 2:QR コード
challenge.urlフィールドから生成された QR コードを表示します。信頼できる大人は携帯電話でこれをスキャンして、同意ポータルに直接アクセスできます。
// チャレンジURLからQRコードを生成
const qrCodeUrl = challenge.url;
// QRコードライブラリを使用してレンダリング: "https://family.k-id.com/authorize?otp=PP5BUS"
オプション 3:手動コード入力
challenge.oneTimePasswordを表示し、信頼できる大人にasktoplay.comにアクセスしてコードを入力するよう指示します。
チャレンジ画面の実装例
<div id="challenge-screen">
<h2>信頼できる大人に助けを求めてください</h2>
<p>
以下のいずれかの方法で、信頼できる大人にセットアップを完了してもらってください。
</p>
<div class="options-container">
<!-- オプション1:メール -->
<div class="option">
<h3>オプション1</h3>
<p>信頼できる大人のメールアドレスを入力</p>
<form id="email-form">
<label for="email">メール</label>
<input type="email" id="email" placeholder="メールアドレス" required />
<button type="submit">送信</button>
</form>
</div>
<!-- オプション2:QRコード -->
<div class="option">
<h3>オプション2</h3>
<p>
信頼できる大人にQRコードをスキャンまたはクリックしてもらってください。
</p>
<div id="qr-code">
<!-- challenge.urlからQRコードをレンダリング -->
</div>
</div>
<!-- オプション3:手動コード -->
<div class="option">
<h3>オプション3</h3>
<p>
<a href="https://asktoplay.com">asktoplay.com</a
>にアクセスし、以下のコードを入力してください。
</p>
<div class="code-display">
<span id="otp-code">PP5BUS</span>
<button onclick="copyCode()">コピー</button>
</div>
</div>
</div>
<button id="do-later">後で行う</button>
</div>
チャレンジの保存
同意を待っている間、challengeIdを保存します。ローカルストレージ、ユーザーのアカウントに関連付けられたデータベース、またはプラットフォームに適した他の永続ストレージに保存できます。ユーザーが同意が許可される前にアプリに戻った場合、/challenge/getを使用してチャレンジを取得し、チャレンジ画面を復元します。
// チャレンジ作成時に保存(localStorageを使用した例)
localStorage.setItem("pendingChallenge", challengeId);
// アプリ再起動時に保留中のチャレンジを確認
const pendingChallenge = localStorage.getItem("pendingChallenge");
if (pendingChallenge) {
// チャレンジの詳細を取得してチャレンジ画面を表示
const challenge = await fetchChallenge(pendingChallenge);
showChallengeScreen(challenge);
}
ステップ 5:Webhook イベントを処理
チャレンジのステータスが変更されたとき、またはセッションが削除されたときにイベントを受信するように Webhook エンドポイントを設定します。
Challenge.StateChangeイベント
このイベントは、信頼できる大人が同意リクエストを承認または拒否したときに発生します。
{
"eventType": "Challenge.StateChange",
"data": {
"id": "683409f1-2930-4132-89ad-827462eed9af",
"productId": 42,
"status": "PASS",
"dob": "2015-04-15",
"sessionId": "0ad1641f-c154-4c2-8bb2-74dbd0de7723",
"approverEmail": "parent@example.com",
"kuid": "7a1f2c3d-4e5f-6789-abcd-ef0123456789"
}
}
| ステータス | 説明 | アクション |
|---|---|---|
PASS | 同意が付与された | sessionIdを保存してアクセスを許可 |
FAIL | 同意が拒否された | 適切なメッセージを表示、ユーザーは続行不可 |
IN_PROGRESS | チャレンジはまだ保留中 | 待機を続ける |
同意成功時の処理
PASSステータスを受け取ったら(Webhook またはポーリング経由)、レスポンスにはsessionIdが含まれます。以下を行う必要があります:
- セッション権限を取得:
sessionIdを使用して/session/getを呼び出し、権限を含む完全なセッション詳細を取得します。
GET /api/v1/session/get?id=0ad1641f-c154-4c2-8bb2-74dbd0de7723
Authorization: Bearer your-api-key
レスポンス例:
{
"session": {
"ageStatus": "DIGITAL_MINOR",
"dateOfBirth": "2015-04-15",
"etag": "6d9d24fccd428f845b355122799948dd0a52fc5d",
"jurisdiction": "US-CA",
"kuid": "7a1f2c3d-4e5f-6789-abcd-ef0123456789",
"permissions": [
{
"enabled": true,
"managedBy": "GUARDIAN",
"name": "text-chat-private"
},
{
"enabled": false,
"managedBy": "GUARDIAN",
"name": "voice-chat"
}
],
"sessionId": "0ad1641f-c154-4c2-8bb2-74dbd0de7723",
"status": "ACTIVE"
},
"status": "PASS"
}
- 保存されたチャレンジをセッションに置き換え:
challengeIdをクリアし、代わりにsessionIdを保存します。これにより、ユーザーが権限を付与されたアクティブなセッションを持っていることが示されます。
// 保留中のチャレンジをクリアしてアクティブなセッションを保存
user.challengeId = null;
user.sessionId = data.sessionId;
- 権限を適用: セッションレスポンスの権限を使用して、アプリケーションの機能を有効または無効にします。
Session.Deleteイベント
このイベントは、セッションが削除されたとき(例えば、保護者が Family Connect を通じてアクセスを取り消したとき)に発生します。
{
"eventType": "Session.Delete",
"data": {
"id": "0ad1641f-c154-4c2-8bb2-74dbd0de7723",
"productId": 42
}
}
アクション:保存されたセッションを削除し、ユーザーに年齢ゲートフローを再度完了させます。
Webhook ハンドラーの例
app.post("/webhook/k-id", (req, res) => {
const { eventType, data } = req.body;
switch (eventType) {
case "Challenge.StateChange":
if (data.status === "PASS") {
// アクセスを許可 - ユーザーのsessionIdを保存
grantAccess(data.sessionId, data.kuid);
} else if (data.status === "FAIL") {
// アクセスを拒否
denyAccess(data.id);
}
break;
case "Session.Delete":
// アクセスを取り消し - ユーザーは再度年齢ゲートを完了する必要がある
revokeSession(data.id);
break;
}
res.status(200).send("OK");
});
フォールバックとしてのポーリング
Webhook が利用できない場合、/challenge/get-statusをポーリングしてチャレンジステータスを確認できます:
GET /api/v1/challenge/get-status?id=683409f1-2930-4132-89ad-827462eed9af
Authorization: Bearer your-api-key
ポーリング時は、リクエスト間で少なくとも 5 秒待ってください。ポーリング頻度が高すぎる場合、API は HTTP 429 を返す可能性があります。
Webhook 設定
カスタム年齢ゲートフローでは、Webhook エンドポイントが以下を受信するように設定されていることを確認してください:
Challenge.StateChange:保護者の同意が承認または拒否されたときに通知Session.Delete:保護者によってセッションが削除されたときに通知
Webhook 署名の検証については、Webhooksを参照してください。
次のステップ
カスタム年齢ゲートを実装したら、以下のリソースを参照して統合を強化してください:
- UXガイドライン:年齢スライダー、日付ピッカー、同意フローのデザイン推奨事項
- API リファレンスドキュメント:年齢ゲートおよびチャレンジ API の詳細なドキュメント
- Webhooks セットアップ:本番システム向けの堅牢な Webhook 処理を実装
- ベストプラクティス:セキュリティと信頼性の高いユーザー体験を確保するためのベストプラクティスを実装
- テスト:テストモード API で統合をテスト
- プリローンチチェックリスト:本番稼働前の要件を確認
k-ID のカスタム年齢ゲート統合により、k-ID が複雑な管轄区域ロジックと保護者同意フローを処理する間、完全にブランド化されたコンプライアンス体験を構築できます。