메인 콘텐츠로 이동

모범 사례

나이 확인 모범 사례

확인 실패 처리

액세스 나이 확인을 구현할 때 개발자는 확인 결과의 failureReason 필드를 확인하여 실패를 적절히 처리해야 합니다:

  • 사기 활동 감지: 확인이 실패하고 failureReasonfraudulent-activity-detected인 경우, 해당 사용자에 대한 추가 확인 시도를 허용하지 마세요.
  • 기타 실패 이유: 다른 모든 실패 이유(예: age-criteria-not-met 또는 max-attempts-exceeded)의 경우, 남용을 방지하면서 합법적인 재시도 시도를 허용하도록 속도 제한을 구현하세요. 24시간당 최대 3회의 확인 시도를 허용하세요. 이는 사용자가 확인 시스템을 우회하려고 반복 시도하는 것을 방지하면서 합법적인 사용자에게 합리적인 재시도 기회를 제공합니다.

보안 권장사항

백엔드 전용 API 호출

중요: 모든 위젯 URL 생성 엔드포인트는 클라이언트 측 코드에서 직접 호출하지 말고 백엔드 서버에서만 호출해야 합니다. k-ID API 키는 보호되어야 하는 비밀 자격 증명입니다:

  • API 키를 안전하게 저장 시크릿 관리자 사용
  • API 키를 노출하지 마세요 프론트엔드 JavaScript, 모바일 앱 코드 또는 클라이언트 측 코드에
  • API 키를 저장하지 마세요 클라이언트 기기나 클라이언트 측 스토리지에

대상 출처 구성

CDK는 Compliance Studio에서 대상 출처를 구성하여 어떤 도메인이 위젯을 임베드할 수 있는지 제어하는 기능을 제공합니다. 이 설정은 콘텐츠 보안 정책의 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;payment;publickey-credentials-get;publickey-credentials-create"
width="100%"
height="600"
></iframe>

권한 분석:

  • camera - 얼굴 나이 추정에 필요
  • payment - 신용카드 확인에 필요
  • publickey-credentials-create - 나이 키 생성에 필요
  • publickey-credentials-get - 나이 키 확인에 필요

출처 검증

들어오는 메시지의 출처를 항상 검증하세요:

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);
});