iframe을 사용하여 원탭 통합

Google 원탭은 광고주의 웹사이트에서 호스팅하는 iframe (이하 중간 iframe) 내부에서 렌더링할 수 있습니다. 중간 iframe이 사용될 때 원탭 UX에서 눈에 띄는 변화가 없습니다.

중간 iframe 기반 통합에는 몇 가지 유연성과 위험이 수반됩니다.

  • 원탭 및 후속 UX 흐름용 UX 내장

    원탭 UX가 완료되면 중간 iframe 내에 후속 UX 흐름을 표시할 수 있습니다. 따라서 원탭과 후속 UX를 모두 현재 콘텐츠 페이지에 삽입할 수 있습니다. 다음 예를 참조하십시오.

    중간 iframe이 있는 삽입된 UX의 예

    중간 iframe이 없으면 일반적으로 후속 UX 흐름을 표시하기 위한 전체 페이지 탐색이 필요하며, 일부 경우에는 방해가 될 수 있습니다.

  • 한 번 통합하여 모든 곳에 표시.

    모든 원탭 통합 코드 (원탭 API 호출 및 후속 UX 처리)는 중간 iframe에 캡슐화됩니다. 원탭이 표시될 수 있는 콘텐츠 페이지에서는 중간 iframe을 삽입하기만 하면 됩니다.

    이 아키텍처를 사용하면 관심사를 분리할 수 있으므로 통합 및 유지보수 비용이 절감됩니다.

  • ID 토큰 노출 범위 제한.

    ID 토큰은 중간 iframe에 의해 직접 사용됩니다. 콘텐츠 페이지에는 절대 노출되지 않습니다. 이 아키텍처는 ID 토큰 노출 범위를 크게 줄일 수 있습니다.

    중간 iframe 방식은 이미 로그인 관련 전용 하위 도메인 (예: login.example.com)과 여러 콘텐츠 관련 하위 도메인 (예: Sports.example.com 및 games.example.com)이 있는 웹사이트에서도 잘 작동합니다.

  • 원탭 표시 도메인.

    Google의 OAuth 정책에 따라 OAuth 응답을 수신하는 모든 도메인은 Google Cloud 콘솔에 사전 등록해야 합니다. 일반적인 원탭 통합에서는 ID 토큰이 이러한 도메인으로 다시 전달되므로 개발자는 원탭에 표시될 수 있는 모든 도메인을 사전 등록해야 합니다. 일부 웹사이트에서는 사용자가 사전 등록이 불가능한 하위 도메인을 동적으로 만들 수 있습니다. 따라서 동적으로 생성된 하위 도메인에는 원탭을 표시할 수 없습니다.

    이 문제는 중간 iframe을 활용하여 해결할 수 있습니다. 이 경우 중간 iframe의 도메인만 사전 등록하면 됩니다. 콘텐츠 페이지 도메인은 ID 토큰이 이러한 콘텐츠 페이지에 노출되지 않으므로 등록할 필요가 없습니다.

  • AMP 지원.

    다음과 같은 이유로 기본적으로 Google 원탭을 AMP 페이지에 표시할 수 없습니다.

    1. 맞춤 JS 라이브러리 또는 코드는 허용되지 않습니다.

    2. AMP 캐시는 다른 (AMP 뷰어) 도메인에서 페이지를 렌더링할 수 있습니다.

    이 문제는 중간 iframe 아키텍처를 활용하여 해결할 수 있습니다. 원탭 통합이 중간 iframe에서 완료되면 개발자는 <amp-onetap-google> 구성요소를 추가하여 AMP 페이지에 이를 삽입할 수 있습니다.

    동일한 중간 iframe을 AMP 페이지와 비 AMP HTML 페이지 모두에서 재사용할 수 있습니다.

  • 개인 정보 보호 위험.

    개발자는 중간 iframe이 예기치 않은 도메인에 삽입되지 않도록 조치를 취해야 합니다. 예를 들어 악성.com은 중간 iframe을 삽입하여 웹사이트에 원탭 UX를 표시할 수 있습니다. 이는 최종 사용자의 개인 정보 보호 문제를 크게 야기할 것입니다.

  • 보안 위험.

    위에서 언급한 예상치 못한 프레이밍 문제로 인해 중간 iframe은 ID 토큰, 세션 쿠키 값, 사용자 데이터 등 보안 또는 개인 정보 보호에 민감한 정보를 상위 프레임으로 전송하면 안 됩니다. 이 규칙을 따르지 않으면 웹사이트가 위험에 처할 수 있습니다.

중간 iframe에서 탭 한 번으로 렌더링

중간 iframe 내에 원탭을 표시하려면 다음 코드 스니펫을 중간 iframe의 HTML 코드에 배치합니다.

<div id="g_id_onload"
     data-client_id="YOUR_GOOGLE_CLIENT_ID"
     data-login_uri="https://your.domain/your_login_endpoint"
     data-allowed_parent_origin="https://example.com">
</div>

data-allowed_parent_origin 속성을 사용하면 Google 원탭이 중간 iframe 모드에서 실행됩니다. 하나의 도메인 또는 쉼표로 구분된 도메인 목록을 속성 값으로 설정할 수 있습니다. 와일드 카드 하위 도메인도 지원됩니다.

(선택사항) 중간 iframe에서 후속 UX 렌더링

로그인 응답에서 HTML 코드를 반환할 수 있으며, 이 경우 최종 사용자에게 일부 콘텐츠가 표시될 수 있습니다. 예를 들어 추가 프로필 정보를 요청하거나 TOS에 동의합니다. 페이지가 제출되면 다른 페이지를 표시할 수 있습니다. 결제 또는 정기 결제를 예로 들 수 있습니다.

중간 iframe의 크기를 조절할 수 있습니다.

<script src="https://accounts.google.com/gsi/intermediatesupport"></script>
<script>
  google.accounts.id.intermediate.notifyParentResize(320);
</script>

요약하면 중간 iframe을 사용하면 전체 로그인 또는 가입 UX 흐름을 삽입된 UX로 구현할 수 있습니다.

원탭 UX 이후의 첫 번째 페이지에서는 다음과 같은 이유로 notifyParentResize() 메서드를 두 번 호출해야 합니다.

  1. 원탭 UX가 완료되면 중간 iframe이 숨김으로 설정됩니다.

  2. 숨겨진 요소의 offsetHeight 속성 값은 0입니다.

첫 번째 호출에서 iframe 높이를 1px로 조절하여 표시되도록 할 수 있습니다. 그런 다음 offsetHeight 속성 값을 사용할 수 있게 되면 적절한 높이로 크기를 조절할 수 있습니다.

다음 코드 예는 원탭 UX 후 상위 출처의 유효성을 검사하고 UI의 중간 iframe 크기를 조절하는 방법을 보여줍니다.

<script>
window.onload = () => {
  google.accounts.id.intermediate.verifyParentOrigin(
    ["https://example.com","https://example-com.cdn.ampproject.org"],
    () => {
      google.accounts.id.intermediate.notifyParentResize(1);
      window.setTimeout(() => {
        let h = document.getElementById('container').offsetHeight;
        google.accounts.id.intermediate.notifyParentResize(h);
      }, 200);
    },
    () => {
      document.getElementById('container').style.display = 'none';
      document.getElementById('warning').innerText = 'Warning: the page is displayed in an unexpected domain!';
    }
  );
};
</script>

UX 완료 시 중간 iframe 삭제

UX 흐름이 완료되면 상위 콘텐츠 페이지에 중간 iframe을 삭제하도록 알려야 합니다. 이를 위해 로그인 응답 코드에 다음 코드 스니펫을 배치할 수 있습니다.

<script src="https://accounts.google.com/gsi/intermediatesupport"></script>
<script>
  google.accounts.id.intermediate.notifyParentDone();
</script>

UX 흐름을 건너뛰면 notifyParentClose 메서드를 대신 호출해야 합니다.

HTML 페이지에 중간 iframe 삽입

Google 원탭을 표시하려는 HTML 페이지에 다음 코드 스니펫을 배치합니다.

<script src="https://accounts.google.com/gsi/intermediate"></script>
<div id="g_id_intermediate_iframe"
     data-src="https://example.com/onetap_iframe.html">
</div>

data-src 속성은 중간 iframe의 URI입니다.