Integrate One Tap using an Iframe

Google One Tap can be rendered inside an iframe (hereinafter referred to as Intermediate Iframe) hosted by your own website. There isn't any perceivable change on One Tap UX when an intermediate iframe is used.

The intermediate iframe based integration brings some flexibilities and risks:

  • Embedded UX for One Tap and subsequent UX flow.

    After the One Tap UX is done, you can display subsequent UX flow inside the intermediate iframe. Thus, One Tap and subsequent UX can be both embedded into the current content page. See an example below.

    An example of the embedded UX with intermediate iframe.

    Without the intermediate iframe, normally you need a full page navigation to display subsequent UX flow, which may be intrusive in some cases.

  • Integrate Once, and Display Everywhere.

    All the One Tap integration code (One Tap API invocation and subsequent UX handling) are encapsulated in the intermediate iframe. On content pages, where One Tap may display, all you need to do is to embed the intermediate iframe.

    This architecture allows the separation of concerns, and thus decreases your integration and maintenance cost.

  • Limit the ID Token Exposure Scope.

    The ID tokens are consumed directly by the intermediate iframe. They are never exposed to the content pages. This architecture may dramatically decrease the ID tokens exposure scope.

    The intermediate iframe way also works well with websites that already have a dedicated login-related sub domain (say, login.example.com) and multiple content-related sub domains (say, sports.example.com and games.example.com).

  • One Tap Displaying Domains.

    As required by Google's OAuth policies, all domains that receive OAuth responses need to be pre-registered in Google Cloud console. With normal One Tap integration, developers need to pre-register all domains that One Tap may display, since ID tokens will be passed back to these domains. Some websites allow their users to dynamically create sub domains, which are impossible to be pre-registered. As a result, One Tap cannot be displayed in these dynamically created sub domains.

    This issue can be fixed by leveraging the intermediate iframe. In this case, only the domain of the intermediate iframe needs to be pre-registered. There is no need to register the content page domains, since ID Tokens are not exposed to these content pages.

  • Privacy Risks.

    Developers must take measures to prevent the intermediate iframes to be embedded into unexpected domains. For example, malicious.com may embed your intermediate iframe, and thus display your One Tap UX on their website. This will definitely cause lots of privacy concerns from end users.

  • Security Risks.

    Due to the above-mentioned unexpected framing issue, your intermediate iframe should never send security or privacy sensitive data to its parent frame, such as ID tokens, session cookie values, user data, etc. Failure to follow this rule may put your websites in danger.

Render One Tap in the Intermediate Iframe

To display One Tap inside the intermediate iframe, place the following code snippet into the HTML code of the intermediate iframe:

<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>

If the data-allowed_parent_origin attribute is used, Google One Tap runs in intermediate iframe mode. You can set one domain or a comma-separated domain list as the attribute value. Wildcard subdomains are also supported.

(Optional) Render Subsequent UX in the Intermediate Iframe

In the login response, you can return whatever HTML code, which may display some visible content to end users. For example, asking for extra profile information, or agreeing on TOS. Once the page is submitted, you can display further pages. For example, for a payment or subscription.

You can resize the intermediate iframe:

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

In summary, with intermediate iframe, the full sign-in or sign-up UX flows can be implemented as embedded UX.

For the first page after One Tap UX, you need to call the notifyParentResize() method twice due to following reasons.

  1. The intermediate iframe is set to hidden when One Tap UX is done.

  2. The offsetHeight attribute value of an element is 0 when it's hidden.

In the first call, you can resize the iframe height to 1px just to make it visible. Then, after the offsetHeight attribute value is available, you can resize it to suitable height.

The following example code shows how to validate parent origin and resize the intermediate iframe for the for UI after One Tap UX.

<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>

Remove the Intermediate Iframe on UX Done

You must notify the parent content page to remove the intermediate iframe when the UX flow is done. To this end, you can place the following code snippet in your login response code.

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

If the UX flow is skipped, the notifyParentClose method need to be called instead.

Embed Intermediate Iframe into HTML Pages

Place the following code snippet into any HTML pages the you want Google One Tap to display:

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

The data-src attribute is the URI of your intermediate iframe.