iframe を使用してワンタップを統合する

Google One Tap は、ご自身のウェブサイトでホストされている iframe(以下、中間 iframe と呼びます)内でレンダリングできます。中間 iframe を使用する場合、ワンタップの UX に目に見える変化はありません。

中間 iframe ベースの統合には、柔軟性とリスクがあります。

  • ワンタップとその後の UX フロー用の埋め込み UX

    ワンタップ UX が完了したら、中間 iframe 内に後続の UX フローを表示できます。したがって、ワンタップとその後の UX の両方を現在のコンテンツ ページに埋め込むことができます。次の例をご覧ください。

    中間 iframe を使用した埋め込み 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 Cloud コンソールで事前に登録する必要があります。通常のワンタップ統合では、ID トークンがこれらのドメインに渡されるため、ワンタップが表示される可能性があるすべてのドメインを事前に登録する必要があります。一部のウェブサイトでは、ユーザーがサブドメインを動的に作成できますが、事前登録することはできません。そのため、動的に作成されたサブドメインではワンタップは表示されません。

    この問題は、中間 iframe を活用することで解決できます。この場合、事前登録が必要なドメインは中間 iframe のドメインのみです。ID トークンはこれらのコンテンツ ページに公開されないため、コンテンツ ページのドメインを登録する必要はありません。

  • プライバシー リスク

    デベロッパーは、中間 iframe が予期しないドメインに埋め込まれないように対策を講じる必要があります。たとえば、malicious.com が中間 iframe を埋め込み、ウェブサイトにワンタップ 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 つのドメインまたはカンマ区切りのドメインリストを設定できます。ワイルドカード サブドメインもサポートされています。

クロスオリジン iframe でワンタップを FedCM と統合する

アプリがクロスオリジンの iframe から One Tap API を呼び出す場合、One Tap API がクロスオリジンの iframe から呼び出される場合は、親フレームのすべてのレベルに allow="identity-credentials-get" 属性を追加する必要があります。アプリが Intermediate Iframe API を使用してワンタップを埋め込む場合は、FedCM のクロスオリジン iframe をサポートしているため、追加の属性は必要ありません。ただし、別の iframe 内に Intermediate Iframe API を使用してページを埋め込む場合は、すべての親 iframe に属性を追加する必要があります。

iframe のオリジンが親オリジンと完全に同じでない場合、iframe はクロスオリジンと見なされます。次に例を示します。

  • 異なるドメイン: https://example1.comhttps://example2.com
  • 異なるトップレベル ドメイン: https://example.ukhttps://example.jp
  • サブドメイン: https://example.comhttps://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() メソッドを 2 回呼び出す必要があります。

  1. ワンタップ UX が完了すると、中間 iframe は非表示に設定されます。

  2. 要素が非表示の場合、要素の 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 メソッドを呼び出す必要があります。

中間 iframe を HTML ページに埋め込む

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 です。