从 Google 登录迁移

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

如果您的客户端使用适用于 JavaScript 的 Google API 客户端库或其他旧版库进行授权,请参阅迁移到 Google Identity 服务了解详情。

身份验证和授权

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

与早期的 Google 登录平台库一样,新的 Google Identity 服务库旨在同时支持身份验证和授权流程。

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

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

如果您的用例涉及授权,请参阅用户授权的工作原理迁移到 Google Identity 服务,确保您的应用使用的是经过改进的新 API。

具体变化

对于用户而言,新的 Google Identity Services 库 在易用性方面进行了诸多改进。其特点包括:

  • 全新的顺畅一键登录和自动登录流程,减少了各个步骤的数量,
  • 更新后的登录按钮,提供用户个性化功能;
  • 在网络上采用一致的品牌推广和统一的登录行为,有助于提升用户对您的理解和信任度,
  • 快速访问内容;用户可以在您网站上的任何位置直接注册和登录,而无需先访问登录页或账号页。

对于开发者,我们一直致力于降低复杂性、提高安全性,并尽快完成集成。其中一些改进包括:

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

登录迁移示例

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

库和配置

早期的 Google 登录平台库 apis.google.com/js/platform.js适用于 JavaScript 的 Google API 客户端库 (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

在大多数情况下,您可以继续使用现有的网站应用客户端 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 和 JavaScript API。

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

在任意页面上使用一键登录

一键登录是一种全新的低摩擦方式,可让用户轻松注册或登录您的网站。 借助该 API,您可以让用户直接从网站的任何页面登录,而无需访问专用登录页面。换句话说,这可让用户灵活地从登录页面以外的页面注册和登录,从而减少注册和登录过程中的摩擦。

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

我们还建议您仅在登录页面或用户账号管理页面上添加 g_id_signin(用于显示个性化登录按钮)。将该按钮与其他联合身份提供程序按钮以及用户名和密码输入字段一起显示,让用户可以选择注册或登录。

令牌响应

在用户登录时,您无需再了解或使用 OAuth 2.0 授权代码、访问令牌或刷新令牌。系统将改为使用 JSON 网络令牌 (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 账号,以便:

  • 在首次注册或登录您的网站时同意分享其用户个人资料,
  • 以后,用户在再次访问您的网站时可使用该 Cookie 登录。

用户可以在您的网站上保持已登录的有效会话,同时保持登录状态、退出账号或切换到其他 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 服务库可能会根据您的配置选项选择性地设置这些跨网域 Cookie:

  • g_state 用于存储用户退出状态,并会在使用“一键登录”弹出式窗口或“自动登录”功能时进行设置,
  • g_csrf_token 是一个双重提交 Cookie,用于防止 CSRF 攻击,并会在调用登录端点时设置。您可以明确设置登录 URI 的值,也可以将其默认设置为当前网页的 URI。在以下情况下,使用以下功能时,系统可能会调用您的登录端点:

    • HTML API 使用 data-ux_mode=redirect 或设置了 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 账号。