Google One タップは、ウェブサイトがホストする iframe(以下「中間 iframe」)内でレンダリングできます。中間 iframe を使用している場合、One Tap UX には認識できる変化はありません。
中間の iframe ベースの統合には、次のような柔軟性とリスクがあります。
ワンタップの埋め込み UX とその後の UX フロー。
ワンタップ UX が完了すると、後続の UX フローを中間 iframe 内に表示できます。そのため、現在のコンテンツ ページに One Tap と後続の UX を埋め込むことができます。次の例をご覧ください。
中間 iframe がない場合、通常は、後続の UX フローを表示するためにページ全体を移動する必要があります。これは煩わしい場合もあります。
一度統合すれば、どこでも表示可能
すべての One Tap 統合コード(One Tap API 呼び出しとその後の UX 処理)は中間 iframe にカプセル化されます。ワンタップで表示できるコンテンツ ページでは、中間の iframe を埋め込むだけです。
このアーキテクチャでは、関心の分離が可能になり、統合とメンテナンスの費用が削減されます。
ID トークンの公開範囲を制限する。
ID トークンは中間 iframe で直接使用されます。コンテンツ ページには公開されません。このアーキテクチャでは、ID トークンの公開スコープが大幅に縮小される可能性があります。
iframe の中継は、ログイン専用のサブドメイン(login.example.com など)やコンテンツ関連のサブドメイン(sports.example.com や Games.example.com など)がすでにあるウェブサイトでも使用できます。
ワンタップでドメインを表示
Google の OAuth ポリシーに従い、OAuth レスポンスを受信するすべてのドメインを Google API Console に事前登録する必要があります。通常の One Tap 統合では、One Tap で表示されるすべてのドメインを事前登録する必要があります。これは、ID トークンがこれらのドメインに戻されるためです。一部のウェブサイトでは、ユーザーがサブドメインを動的に作成できますが、事前登録は不可能です。そのため、動的に作成されたサブドメインではワンタップを表示できません。
この問題は、中間 iframe を利用することで解決できます。この場合は、中間 iframe のドメインのみが事前登録されます。ID トークンはコンテンツ ページに公開されないため、コンテンツ ページのドメインを登録する必要はありません。
AMP サポート。
デフォルトでは、Google One タップは以下の理由により AMP ページに表示されません。
カスタムの JS ライブラリやコードは使用できません。
AMP キャッシュは、別の(AMP ビューア)ドメインでページを表示することがあります。
この問題は、中間の iframe アーキテクチャを利用することで解決できます。 ワンタップで中間 iframe を統合したら、<amp-onetap-google> コンポーネントを追加して AMP ページに埋め込むことができます。
AMP ページと非 AMP HTML ページの両方で同じ中間 iframe を再利用できます。
プライバシー リスク。
デベロッパーは、中間 iframe が予期せぬドメインに埋め込まれないように対策を講じる必要があります。たとえば、悪意のあるサイトによって中間 iframe が埋め込まれ、One Tap UX がウェブサイトに表示されない場合があります。その結果、エンドユーザーのプライバシーに関する多くの懸念が生じることになります。
セキュリティ リスク。
上記の予期しないフレームの問題により、中間 iframe は、セキュリティ トークンやプライバシーにかかわる機密データ(ID トークン、セッション Cookie の値、ユーザーデータなど)を親フレームに送信しないようにする必要があります。このルールに従わないと、ウェブサイトが危険にさらされる可能性があります。
中間 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 モードで実行されます。1 つのドメインまたはカンマ区切りのドメインリストを属性値として設定できます。ワイルドカード サブドメインもサポートされます。
(省略可)後続の UX を中間 iframe にレンダリングする
ログイン レスポンスでは、エンドユーザーに一部の可視コンテンツが表示される可能性のある任意の HTML コードを返すことができます。たとえば、追加のプロフィール情報の要求や、利用規約への同意などです。ページを送信すると、さらにページを表示できます。(支払い、定期購入など)。
次のように、中間 iframe のサイズを変更することもできます。
<script src="https://accounts.google.com/gsi/intermediatesupport"></script> <script> google.accounts.id.intermediate.notifyParentResize(320); </script>
要約すると、中間 iframe を使用すると、完全なログインまたは申し込みの UX フローを埋め込み UX として実装できます。
ワンタップ UX の後の最初のページでは、以下の理由により、notifyParentResize()
メソッドを 2 回呼び出す必要があります。
ワンタップ UX が完了すると、中間 iframe は非表示に設定されます。
非表示の場合、要素の
offsetHeight
属性値は 0 です。
最初の呼び出しでは、iframe の高さを 1 px に変更して、視認性を高めることができます。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 Done Intermediate iFrame] を削除する
UX フローが終了したら、中間コンテンツ ページに連絡して、中間 iframe を削除するように通知する必要があります。この目的を達成するため、ログイン レスポンス コードに次のコード スニペットを配置します。
<script src="https://accounts.google.com/gsi/intermediatesupport"></script> <script> google.accounts.id.intermediate.notifyParentDone(); </script>
UX フローがスキップされた場合は、代わりに notifyParentClose
メソッドを呼び出す必要があります。
中間 iframe を HTML ページに埋め込む
次のコード スニペットを、Google One タップで表示する 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 です。