Google One Tap은 자체 웹사이트에서 호스팅하는 iframe (이하 중간 iframe이라고 함) 내에서 렌더링될 수 있습니다. 중간 iframe이 사용될 때 원탭 UX에는 감지할 수 있는 변화가 없습니다.
중간 iframe 기반 통합은 다음과 같은 유연성과 위험을 가져옵니다.
원탭 및 후속 UX 흐름을 위한 삽입된 UX
원탭 UX가 완료되면 중간 iframe 내에 후속 UX 흐름을 표시할 수 있습니다. 따라서 원탭 및 후속 UX를 모두 현재 콘텐츠 페이지에 삽입할 수 있습니다. 다음 예를 참조하십시오.
중간 iframe이 없으면 일반적으로 후속 UX 흐름을 표시하기 위해 전체 페이지 탐색이 필요하며, 이는 경우에 따라 방해가 될 수 있습니다.
한 번 통합하면 어디서나 표시
모든 원탭 통합 코드 (원탭 API 호출 및 후속 UX 처리)는 중간 iframe에 캡슐화됩니다. 원탭이 표시될 수 있는 콘텐츠 페이지에서는 중간 iframe을 삽입하기만 하면 됩니다.
이 아키텍처를 사용하면 관심분야를 분리할 수 있으므로 통합 및 유지보수 비용이 줄어듭니다.
ID 토큰 노출 범위 제한
ID 토큰은 중간 iframe에서 직접 사용합니다. 콘텐츠 페이지에는 노출되지 않습니다. 이 아키텍처는 ID 토큰 노출 범위를 크게 줄일 수 있습니다.
중간 iframe 방식은 이미 전용 로그인 관련 하위 도메인 (예: login.example.com)과 여러 콘텐츠 관련 하위 도메인 (예: sports.example.com 및 games.example.com)이 있는 웹사이트에서도 잘 작동합니다.
One Tap Displaying Domains(원탭 디스플레이 도메인)
Google의 OAuth 정책에 따라 OAuth 응답을 수신하는 모든 도메인은 Google Cloud 콘솔에 사전 등록되어야 합니다. 일반 원탭 통합을 사용하는 경우 ID 토큰이 이러한 도메인으로 다시 전달되므로 개발자는 원탭에 표시될 수 있는 모든 도메인을 사전 등록해야 합니다. 일부 웹사이트에서는 사용자가 사전 등록할 수 없는 하위 도메인을 동적으로 만들 수 있습니다. 따라서 동적으로 생성된 하위 도메인에는 원탭을 표시할 수 없습니다.
이 문제는 중간 iframe을 활용하여 해결할 수 있습니다. 이 경우 중간 iframe의 도메인만 사전 등록하면 됩니다. ID 토큰이 이러한 콘텐츠 페이지에 노출되지 않으므로 콘텐츠 페이지 도메인을 등록할 필요가 없습니다.
개인 정보 보호 위험
개발자는 중간 iframe이 예기치 않은 도메인에 삽입되지 않도록 조치를 취해야 합니다. 예를 들어 malicious.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 One Tap이 중간 iframe 모드로 실행됩니다. 하나의 도메인 또는 쉼표로 구분된 도메인 목록을 속성 값으로 설정할 수 있습니다. 와일드 카드 하위 도메인도 지원됩니다.
교차 출처 iframe에서 원탭을 FedCM과 통합
교차 출처 iframe에서 One Tap API가 호출되는 경우 앱이 교차 출처 iframe에서 One Tap API를 호출하는 경우 모든 수준의 상위 프레임에 allow="identity-credentials-get"
속성을 추가해야 합니다.
앱에서 Intermediate Iframe API를 사용하여 원탭을 삽입하는 경우 FedCM 교차 출처 iframe을 지원하므로 추가 속성이 필요하지 않습니다.
하지만 다른 iframe 내에 Intermediate Iframe API를 사용하여 페이지를 삽입하는 경우 모든 상위 iframe에 속성을 추가해야 합니다.
iframe의 출처가 상위 요소의 출처와 정확히 일치하지 않으면 교차 출처로 간주됩니다. 예를 들면 다음과 같습니다.
- 다른 도메인:
https://example1.com
및https://example2.com
- 다른 최상위 도메인:
https://example.uk
및https://example.jp
- 하위 도메인:
https://example.com
및https://login.example.com
교차 출처 iframe에서 원탭을 사용하면 사용자에게 혼란스러운 환경이 발생할 수 있습니다. 원탭 메시지는 사용자 인증 정보 도용을 방지하기 위한 보안 조치로 iframe이 아닌 최상위 도메인의 이름을 표시합니다. 하지만 ID 토큰은 iframe의 출처에 발급됩니다. 자세한 내용은 이 GitHub 문제를 참고하세요.
이러한 불일치는 혼동을 줄 수 있으므로 교차 출처 iframe에서는 원탭만 사용하고 동일 사이트 iframe에서는 사용하지 않는 것이 지원되는 방법입니다. 예를 들어 최상위 도메인 https://www.example.com
의 페이지에서 iframe을 사용하여 https://login.example.com
의 원탭으로 페이지를 삽입합니다. 탭 한 번 메시지에 'google.com으로 example.com에 로그인'이라고 표시됩니다.
다른 도메인과 같은 다른 모든 경우에는 지원되지 않습니다. 대신 다음과 같은 대체 통합 방법을 고려하세요.
- Google 계정으로 로그인 버튼 구현
- 최상위 도메인에 원탭 구현
- Google OAuth 2.0 엔드포인트를 활용하여 맞춤설정된 통합을 제공합니다.
- iframe 내에 서드 파티 사이트를 삽입하고 원탭 구현을 수정할 수 없는 경우 원탭 메시지가 iframe 내에 표시되지 않도록 할 수 있습니다. 이렇게 하려면 상위 프레임의 iframe 태그에서
allow="identity-credentials-get"
속성을 삭제합니다. 이렇게 하면 메시지가 표시되지 않으며, 개발자는 사용자를 삽입된 사이트의 로그인 페이지로 직접 안내할 수 있습니다.
(선택사항) 중간 iframe에서 후속 UX 렌더링
로그인 응답에서 어떤 HTML 코드든 반환할 수 있으며, 이 코드는 최종 사용자에게 표시되는 콘텐츠를 표시할 수 있습니다. 예를 들어 추가 프로필 정보를 요청하거나 이용약관에 동의하는 경우입니다. 페이지가 제출되면 추가 페이지를 표시할 수 있습니다. 예를 들어 결제 또는 정기 결제에 사용할 수 있습니다.
중간 iframe의 크기를 조절할 수 있습니다.
<script src="https://accounts.google.com/gsi/intermediatesupport"></script>
<script>
google.accounts.id.intermediate.notifyParentResize(320);
</script>
요약하면 중간 iframe을 사용하면 전체 로그인 또는 가입 UX 흐름을 삽입된 UX로 구현할 수 있습니다.
원탭 UX 후 첫 번째 페이지의 경우 다음과 같은 이유로 notifyParentResize()
메서드를 두 번 호출해야 합니다.
원탭 UX가 완료되면 중간 iframe이 숨김으로 설정됩니다.
요소가 숨겨져 있으면 요소의
offsetHeight
속성 값은 0입니다.
첫 번째 호출에서 iframe 높이를 1픽셀로 조정하여 표시되도록 할 수 있습니다. 그런 다음 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 One Tap을 표시하려는 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입니다.