从 Google 登录迁移

本指南可帮助您了解成功将 JavaScript 库从旧版 Google 登录平台库迁移到新版 Google Identity 服务库以进行身份验证所需进行的更改和步骤。

如果您的客户端使用 JavaScript 版 Google API 客户端库或其他较早的库进行授权,请参阅迁移到 Google Identity Services 以了解详情。

身份验证和授权

身份验证用于确定用户身份,通常称为用户注册或登录。授权是授予或拒绝访问数据或资源的过程。例如,您的应用请求用户同意访问用户的 Google 云端硬盘。

与之前的 Google 登录平台库类似,新的 Google Identity 服务库旨在同时支持身份验证和授权流程。

不过,新版库将这两个流程分开,以降低开发者将 Google 账号与应用集成的复杂性。

如果您的使用情形仅涉及身份验证,请继续阅读本页内容。

如果您的使用情形涉及授权,请阅读用户授权的运作方式迁移到 Google Identity Services,确保您的应用使用的是经过改进的新 API。

具体变化

对于用户而言,新的 Google Identity 服务库在易用性方面做出了多项改进。其特点包括:

  • 新的顺畅的一键快捷功能和自动登录流程,可减少个人操作步骤,
  • 经过更新的登录按钮,可实现用户个性化,
  • 在整个网络中保持一致的品牌宣传和统一的登录行为有助于提高用户理解度和信任度,
  • 快速访问内容;用户可以直接从您网站上的任何位置注册和登录,而无需先访问登录页或账号页。

对于开发者,我们的重点是降低复杂性、提高安全性,并尽可能加快集成速度。其中一些改进包括:

  • 仅使用 HTML 将用户登录功能添加到网站的静态内容中,
  • 将登录身份验证与授权和用户数据共享分开,因此不再需要复杂的 OAuth 2.0 集成即可让用户登录您的网站,
  • 弹出式和重定向模式仍受支持,但 Google 的 OAuth 2.0 基础架构现在会重定向到后端服务器的登录端点,
  • 将之前两个 Google Identity 和 Google API JavaScript 库的功能整合到一个新的库中,
  • 对于登录响应,您现在可以决定是否使用 Promise,并且为了简单起见,已移除通过 getter 样式函数进行的间接调用。

登录迁移示例

如果您要从现有的 Google 登录按钮进行迁移,并且只希望用户登录您的网站,最直接的更改是更新为新的个性化按钮。为此,您可以替换 JavaScript 库,并更新代码库以使用新的登录对象。

库和配置

之前的 Google 登录平台库:apis.google.com/js/platform.js,以及 Google API 客户端库(适用于 JavaScript)gapi.client,不再是用户身份验证和授权所必需的。它们已被单个新的 Google Identity 服务 JavaScript 库取代:accounts.google.com/gsi/client

之前用于登录的三个 JavaScript 模块:apiclientplatform 均从 apis.google.com 加载。为了帮助您确定网站中可能包含旧版库的位置,通常:

  • 默认登录按钮加载 apis.google.com/js/platform.js
  • 自定义按钮图形加载 apis.google.com/js/api:client.js,并且
  • 直接使用 gapi.client 会加载 apis.google.com/js/api.js

在大多数情况下,您可以继续使用现有的 Web 应用客户端 ID 凭据。在迁移过程中,我们建议您查看我们的 OAuth 2.0 政策,并使用 Google API 控制台确认以下客户端设置,并在必要时进行更新:

  • 您的测试应用和生产应用使用不同的项目,并且有各自的客户端 ID,
  • OAuth 2.0 客户端 ID 类型为“Web 应用”,并且
  • HTTPS 用于已获授权的 JavaScript 来源和重定向 URI。

确定受影响的代码并进行测试

调试 Cookie 有助于找到受影响的代码并测试弃用后的行为。

在大型或复杂的应用中,可能很难找到受 gapi.auth2 模块弃用影响的所有代码。如需将即将弃用的功能的现有使用情况记录到控制台,请将 G_AUTH2_MIGRATION Cookie 的值设置为 informational。(可选)添加一个英文冒号,后跟一个键值,以便同时记录到会话存储空间。登录并收到凭据后,检查或将收集的日志发送到后端以供日后分析。例如,informational:showauth2use 会将来源和网址保存到名为 showauth2use 的会话存储键中。

如需验证应用在 gapi.auth2 模块不再加载时的行为,请将 G_AUTH2_MIGRATION Cookie 的值设置为 enforced。这样一来,您就可以在强制执行日期之前测试弃用后的行为。

可能的 G_AUTH2_MIGRATION Cookie 值:

  • enforced 不加载 gapi.auth2 模块。
  • informational 将已弃用功能的使用情况记录到 JS 控制台。当设置了可选的键名时,也记录到会话存储空间:informational:key-name

为尽可能减少对用户的影响,建议您先在开发和测试期间本地设置此 Cookie,然后再在生产环境中使用。

HTML 和 JavaScript

在此仅进行身份验证的登录方案中,显示了现有 Google 登录按钮的示例代码和渲染效果。选择弹出式窗口模式或重定向模式,了解 JavaScript 回调或安全重定向到后端服务器登录端点如何处理身份验证响应。

之前的方式

呈现 Google 登录按钮,并使用回调直接从用户的浏览器处理登录。

<html>
  <body>
    <script src="https://apis.google.com/js/platform.js" async defer></script>
    <meta name="google-signin-client_id" content="YOUR_CLIENT_ID">
    <div class="g-signin2" data-onsuccess="handleCredentialResponse"></div>
  </body>
</html>

重定向模式

呈现 Google 登录按钮,最后通过 AJAX 调用从用户浏览器发送到后端服务器登录端点。

<html>
  <body>
    <script src="https://apis.google.com/js/platform.js" async defer></script>
    <meta name="google-signin-client_id" content="YOUR_CLIENT_ID">
    <div class="g-signin2" data-onsuccess="handleCredentialResponse"></div>
    <script>
      function handleCredentialResponse(googleUser) {
        ...
        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'https://yourbackend.example.com/tokensignin');
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onload = function() {
          console.log('Signed in as: ' + xhr.responseText);
        };
        xhr.send('idtoken=' + id_token);
      }
    </script>
  </body>
</html>

已渲染

新的视觉属性简化了之前创建自定义按钮的方法,无需调用 gapi.signin2.render(),也无需您在自己的网站上托管和维护图片及视觉资源。

Google 登录

Google 登录

用户登录状态更新按钮文本。

新方式

如需在仅进行身份验证的登录场景中使用新库,请选择弹出模式或重定向模式,并使用代码示例替换登录页面上的现有实现。

使用回调直接从用户的浏览器处理登录。

<html>
  <body>
    <script src="https://accounts.google.com/gsi/client" async defer></script>
    <div id="g_id_onload"
         data-client_id="YOUR_CLIENT_ID"
         data-callback="handleCredentialResponse">
    </div>
    <div class="g_id_signin" data-type="standard"></div>
  </body>
</html>

重定向模式

Google 会调用 data-login_url 属性指定的登录端点。以前,您负责 POST 操作和参数名称。新库会将 ID 令牌以 credential 参数的形式发布到您的端点。最后,在后端服务器上验证 ID 令牌

<html>
  <body>
    <script src="https://accounts.google.com/gsi/client" async defer></script>
    <div id="g_id_onload"
         data-client_id="YOUR_CLIENT_ID"
         data-ux_mode="redirect"
         data-login_uri="https://www.example.com/your_login_endpoint">
    </div>
    <div class="g_id_signin" data-type="standard"></div>
  </body>
</html>

已渲染

使用 visual-attributes 自定义“使用 Google 账号登录”按钮的大小、形状和颜色。显示“一键登录”弹出式窗口以及个性化按钮,以提高登录率。

“使用 Google 账号登录”按钮 “一键登录”弹出式窗口

用户登录状态未将按钮文字从“登录”更新为“已登录”。在用户提供同意声明后或在回访时,个性化按钮会包含用户的姓名、电子邮件地址和个人资料照片。

在这个仅用于身份验证的示例中,新的 accounts.google.com/gsi/client 库、g_id_signin 类和 g_id_onload 对象取代了之前的 apis.google.com/js/platform.js 库和 g-signin2 对象。

除了呈现新的个性化按钮之外,示例代码还会显示新的“一键登录”弹出式窗口。无论您在何处显示个性化按钮,我们都强烈建议您同时显示“一键快捷功能”弹出式窗口,以最大限度地减少用户在注册和登录期间遇到的阻力。

虽然不建议这样做(因为会增加登录难度),但新的个性化按钮可以单独显示,而无需同时显示一键快捷功能对话框。为此,请将 data-auto_prompt 属性设置为 false

HTML 和 JavaScript API

上一个示例展示了如何使用新的 HTML API 为您的网站添加登录功能。或者,您也可以使用功能相同的 JavaScript API,或在整个网站中混用 HTML API 和 JavaScript API。

如需以互动方式查看按钮自定义选项(例如回调类型)和属性(例如颜色、大小、形状、文字和主题),请查看我们的代码生成器。您可以使用此工具快速比较不同选项,并生成可在网站上使用的 HTML 代码段。

通过“一键登录”功能从任何页面登录

一键快捷功能是一种新的低摩擦方式,可让用户注册或登录您的网站。借助此功能,您可以直接从网站上的任何网页启用用户登录,而无需用户访问专用登录页面。换句话说,通过允许用户从登录页面以外的页面注册和登录,此功能可减少注册和登录过程中的阻碍。

为了能够从任何页面登录,我们建议您在整个网站中包含的共享标题、页脚或其他对象中添加 g_id_onload

我们还建议您仅在登录或用户账号管理页面上添加 g_id_signin,该代码会显示个性化的登录按钮。通过在其他联合身份提供方按钮以及用户名和密码输入字段旁边显示该按钮,为用户提供注册或登录选项。

令牌响应

用户登录不再需要您了解或使用 OAuth 2.0 授权代码、访问令牌或刷新令牌。而是使用 JSON Web 令牌 (JWT) ID 令牌来共享登录状态和用户个人资料。为了进一步简化,您不再需要使用“getter”样式的访问器方法来处理用户个人资料数据。

系统会返回一个带有 Google 签名的安全 JWT ID 令牌凭据,具体方式如下:

  • 以弹出模式发送到用户的基于浏览器的 JavaScript 回调处理程序,或
  • 当“使用 Google 账号登录”按钮 ux_mode 设置为 redirect 时,通过 Google 重定向到登录端点。

在这两种情况下,请通过移除以下内容来更新现有回调处理程序:

  • googleUser.getBasicProfile() 的调用,
  • BasicProfile 的引用,以及对 getId()getName()getGivenName()getFamilyName()getImageUrl()getEmail() 方法的相关调用,以及
  • AuthResponse 对象的使用情况。

请改用对新 JWT CredentialResponse 对象中 credential 子字段的直接引用来处理用户个人资料数据。

此外,仅对于重定向模式,请务必防止跨站请求伪造 (CSRF) 并在后端服务器上验证 Google ID 令牌

为了更好地了解用户与您网站的互动情况,您可以使用 CredentialResponse 中的 select_by 字段来确定用户同意结果和所用的具体登录流程。

当用户首次登录您的网站时,Google 会提示用户同意与您的应用分享其账号个人资料。只有在用户同意后,系统才会通过 ID 令牌凭据载荷将用户的个人资料分享给您的应用。撤消对相应配置文件的访问权限相当于撤消之前登录库中的访问令牌。

用户可以访问 https://myaccount.google.com/permissions,撤消权限并将您的应用与其 Google 账号断开连接。 或者,他们也可以通过触发您实现的 API 调用直接从您的应用断开连接;之前的 disconnect 方法已被更新的 revoke 方法取代。

当用户在您的平台上删除其账号时,最佳实践是使用 revoke 将您的应用与其 Google 账号断开连接。

以前,auth2.signOut() 可用于帮助管理用户从应用中退出。现在,应移除所有 auth2.signOut() 的用法,并且应用应直接管理每个用户的会话状态和登录状态。

会话状态和监听器

新库不会为您的 Web 应用维护登录状态或会话状态。

Google 账号的登录状态与应用会话状态和登录状态是不同的概念。

用户登录 Google 账号和登录您应用的状态是相互独立的,除非在登录时,您知道用户已成功完成身份验证并登录其 Google 账号。

如果您的网站上包含“使用 Google 账号登录”“一键快捷功能”或“自动登录”功能,用户必须先登录自己的 Google 账号,才能:

  • 在首次注册或登录您的网站时,同意分享其用户个人资料,
  • 并在日后回访您的网站时用于登录。

用户可以在您的网站上保持已登录的有效会话,也可以保持登录状态、退出登录或切换到其他 Google 账号。

现在,您需要直接管理 Web 应用用户的登录状态。以前,Google 登录可帮助您监控用户会话状态

移除对 auth2.attachClickHandler() 及其注册的回调处理程序的所有引用。

之前,监听器用于分享用户 Google 账号的登录状态变化。监听器不再受支持。

移除对 listen()auth2.currentUserauth2.isSignedIn 的所有引用。

Cookie

使用 Google 账号登录功能会有限地使用 Cookie,下面将介绍这些 Cookie。如需详细了解 Google 使用的其他类型的 Cookie,请参阅 Google 如何使用 Cookie

不再使用旧版 Google 登录平台库设置的 G_ENABLED_IDPS Cookie。

新的 Google Identity Services 库可能会根据您的配置选项选择性地设置以下跨网域 Cookie:

  • g_state 存储用户退出状态,在使用一键快捷功能弹出式内容(窗口/广告/etc.)或自动登录时设置,
  • g_csrf_token 是一个双重提交 Cookie,用于防止 CSRF 攻击,并在调用登录端点时设置。登录 URI 的值可以显式设置,也可以默认为当前网页的 URI。使用以下服务时,系统可能会在以下情况下调用您的登录端点:

    • 使用 data-ux_mode=redirectHTML API 或设置了 data-login_uri 时,或

    • 使用 ux_mode=redirectJavaScript API,其中 google.accounts.id.prompt() 不用于显示一键登录或自动登录。

如果您有管理 Cookie 的服务,请务必在迁移完成后添加两个新 Cookie 并移除之前的 Cookie。

如果您管理多个网域或子网域,请参阅在子网域中显示“一键登录”,详细了解如何使用 g_state Cookie。

用户登录的对象迁移参考文档

旧优惠 备注
JavaScript 库
apis.google.com/js/platform.js accounts.google.com/gsi/client 以新换旧。
apis.google.com/js/api.js accounts.google.com/gsi/client 以新换旧。
GoogleAuth 对象和关联方法:
GoogleAuth.attachClickHandler() IdConfiguration.callback (适用于 JS 和 HTML)data-callback 以新换旧。
GoogleAuth.currentUser.get() CredentialResponse 请改用 CredentialResponse,不再需要。
GoogleAuth.currentUser.listen() 移除。用户的当前 Google 登录状态不可用。 用户必须登录 Google 才能进行同意和登录。 CredentialResponse 中的 select_by 字段可用于确定用户同意情况以及所用的登录方法。
GoogleAuth.disconnect() google.accounts.id.revoke 以新换旧。您还可以通过 https://myaccount.google.com/permissions 撤消许可
GoogleAuth.grantOfflineAccess() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
GoogleAuth.isSignedIn.get() 移除。用户的当前 Google 登录状态不可用。用户必须登录 Google 才能进行意见征求和登录。
GoogleAuth.isSignedIn.listen() 移除。用户的当前 Google 登录状态不可用。用户必须登录 Google 才能进行意见征求和登录。
GoogleAuth.signIn() 移除。对 g_id_signin 元素进行 HTML DOM 加载或对 google.accounts.id.renderButton 进行 JS 调用会触发用户登录 Google 账号。
GoogleAuth.signOut() 移除。应用和 Google 账号的用户登录状态是相互独立的。Google 不会管理您应用中的会话状态。
GoogleAuth.then() 移除。GoogleAuth 已弃用。
GoogleUser 对象和关联方法:
GoogleUser.disconnect() google.accounts.id.revoke 以新换旧。您还可以通过 https://myaccount.google.com/permissions 撤消许可
GoogleUser.getAuthResponse()
GoogleUser.getBasicProfile() CredentialResponse 直接使用 credential 和子字段,而不是 BasicProfile 方法。
GoogleUser.getGrantedScopes() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
GoogleUser.getHostedDomain() CredentialResponse 请直接使用 credential.hd
GoogleUser.getId() CredentialResponse 请直接使用 credential.sub
GoogleUser.grantOfflineAccess() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
GoogleUser.grant() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
GoogleUser.hasGrantedScopes() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
GoogleUser.isSignedIn() 移除。用户的当前 Google 登录状态不可用。用户必须登录 Google 才能进行意见征求和登录。
GoogleUser.reloadAuthResponse() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2 对象和关联的方法:
gapi.auth2.AuthorizeConfig 对象 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2.AuthorizeResponse 对象 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2.AuthResponse 对象 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2.authorize() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2.ClientConfig() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2.getAuthInstance() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2.init() 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2.OfflineAccessOptions 对象 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.auth2.SignInOptions 对象 移除。ID 令牌已取代 OAuth 2.0 访问令牌和范围。
gapi.signin2 对象和关联方法:
gapi.signin2.render() 移除。对 g_id_signin 元素进行 HTML DOM 加载或对 google.accounts.id.renderButton 进行 JS 调用会触发用户登录 Google 账号。