使用 iframe 集成一键快捷功能

Google One Tap 可在由您自己的网站托管的 iframe(以下称为中间 iframe)内呈现。使用中间 iframe 时,一键式用户体验没有任何可察觉的变化。

基于 iframe 的中间集成带来了一些灵活性和风险:

  • 适用于一键快捷功能及后续用户体验流程的嵌入式用户体验

    完成一键式用户体验后,您可以在中间 iframe 内显示后续用户体验流程。因此,“一键快捷”功能和后续用户体验可同时嵌入到当前的内容页面中。以下是一个示例。

    使用中间 iframe 的嵌入式用户体验的示例。

    在没有中间 iframe 的情况下,您通常需要进行整页导航才能显示后续用户体验流程,而这可能会在某些情况下造成干扰。

  • 一次集成,随处展示

    所有一键式集成代码(One Tap API 调用和后续用户体验处理)都封装在中间 iframe 中。在内容页面上,一键快捷功能可能会显示,您只需要嵌入中间 iframe 即可。

    此架构可以分离关注点,从而降低集成和维护成本。

  • 限制 ID 令牌公开范围

    中间 iframe 会直接使用 ID 令牌。它们永远不会提供给内容页面。此架构可能会大幅缩小 ID 令牌公开范围。

    对于已拥有与登录相关的专用子网域(例如 login.example.com)和多个内容相关子网域(例如 sports.example.com 和 games.example.com)的网站来说,中间 iframe 的效果也很好。

  • 一键显示域名

    根据 Google OAuth 政策的要求,所有接收 OAuth 响应的网域都需要在 Google Cloud 控制台中预注册。在常规的一键式集成中,开发者需要预注册一键快捷功能可能会显示的所有网域,因为 ID 令牌将回传给这些网域。有些网站允许用户动态创建子网域,而这些子网域无法预注册。因此,一键快捷功能不能显示在这些动态创建的子网域中。

    使用中间 iframe 可以解决此问题。在这种情况下,只需预注册中间 iframe 的网域。无需注册内容页域名,因为 ID 令牌不会提供给这些内容页。

  • AMP 支持

    默认情况下,Google 一键快捷功能无法在 AMP 网页中显示,原因如下:

    1. 不允许使用自定义 JS 库或代码。

    2. AMP 缓存可能会通过其他(AMP 查看工具)网域呈现网页。

    使用中间 iframe 架构可以解决此问题。在中间 iframe 中完成一键集成后,开发者可以通过添加 <amp-onetap-google> 组件将其嵌入到 AMP 网页中。

    AMP 网页和非 AMP HTML 网页可以重复使用相同的中间 iframe。

  • 隐私风险

    开发者必须采取措施,防止中间 iframe 被嵌入到非预期网域中。例如,Malware.com 可能会嵌入您的中间 iframe,从而在其网站上显示您的一键用户体验。这无疑会引起最终用户的许多隐私问题。

  • 安全风险

    由于上述意外的框架问题,您的中间 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 一键快捷功能会在中间 iframe 模式下运行。您可以将一个网域或以英文逗号分隔的网域列表设置为属性值。系统也支持通配符子网域。

(可选)在中间 iframe 中呈现后续用户体验

在登录响应中,您可以返回任何 HTML 代码,这可能会向最终用户显示一些可见内容。例如,要求提供额外的个人资料信息或同意服务条款 (TOS)。页面提交后,您可以显示更多页面。 例如,对于付款或订阅。

您可以调整中间 iframe 的大小:

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

总而言之,使用中间 iframe 时,完整的登录或注册用户体验流程可以作为嵌入式用户体验来实现。

对于一键式用户体验之后的第一页,由于以下原因,您需要调用两次 notifyParentResize() 方法。

  1. 完成一键式用户体验后,中间 iframe 会设置为隐藏。

  2. 元素隐藏时,其 offsetHeight 属性值为 0。

在首次调用中,您可以将 iframe 的高度调整为 1px,使其可见。然后,在 offsetHeight 属性值可用后,您可以将其大小调整为合适的高度。

以下示例代码展示了如何在一键式用户体验之后验证父级来源并调整界面的中间 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>

在用户体验完成时移除中间 iframe

用户体验流程完成后,您必须通知父内容页面移除中间 iframe。为此,您可以将以下代码段放入登录响应代码中。

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

如果跳过了用户体验流程,则需要改为调用 notifyParentClose 方法。

将中间 iframe 嵌入到 HTML 页面中

将以下代码段放置在您希望 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。