본문으로 건너뛰기

모범 사례

연령 확인 모범 사례

확인 실패 처리

액세스 연령 확인을 구현할 때 개발자는 확인 결과의 failureReason 필드를 확인하여 실패를 올바르게 처리해야 합니다:

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

보안 권장 사항

서버 전용 API 호출

중요

모든 위젯 URL 생성 엔드포인트는 서버에서만 호출해야 하며 클라이언트 측 코드에서 직접 호출해서는 안 됩니다.

k-ID API 키는 보호해야 하는 비밀 자격 증명입니다:

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

대상 원본 구성

CDK는 Compliance Studio에서 대상 원본을 구성하는 기능을 제공하여 어떤 도메인이 위젯을 포함할 수 있는지 제어합니다. 이 설정은 Content Security Policy의 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 - AgeKey 생성에 필요
  • publickey-credentials-get - AgeKey 확인에 필요

원본 검증

들어오는 메시지의 원본을 항상 검증하세요:

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