环回 IP 地址流程迁移指南

概览

我们于 2022 年 2 月 16 日 宣布了以下计划:采用更安全的 OAuth 流程,让 Google OAuth 互动更安全。本指南可帮助您了解从环回 IP 地址流成功迁移到支持的替代方案所需的更改和步骤。

此措施是一种保护措施,可在用户与 Google 的 OAuth 2.0 授权端点互动期间防范钓鱼式攻击和应用冒充攻击。

环回 IP 地址流是什么?

环回 IP 地址流支持使用环回 IP 地址或 localhost 作为重定向 URI 的主机组件,在用户批准 OAuth 同意请求后,该 URI 将发送到该 URI。此流程容易受到中间人攻击。在此类攻击中,访问某些操作系统上的同一环回接口的恶意应用可能会拦截从授权服务器到指定重定向 URI 的响应,并获得对授权代码的访问权限。

对于原生 iOS、Android 和 Chrome OAuth 客户端类型,我们即将弃用环回 IP 地址流,但桌面应用将继续支持该流。

重要合规日期

  • 2022 年 3 月 14 日 - 禁止新的 OAuth 客户端使用环回 IP 地址流
  • 2022 年 8 月 1 日 - 不合规的 OAuth 请求可能会向用户显示一条警告消息
  • 2022 年 8 月 31 日 - 2022 年 3 月 14 日之前创建的原生 Android、Chrome 应用和 iOS OAuth 客户端将阻止环回 IP 地址流
  • 2022 年 10 月 21 日 - 所有现有客户都会被屏蔽(包括豁免的客户端)

对于不合规的请求,系统会显示一条向用户显示的错误消息。该消息将告知用户应用已被屏蔽,同时显示您在 Google API 控制台的 OAuth 同意屏幕中注册的支持电子邮件地址。

完成迁移过程需要完成两个主要步骤:
  1. 确定您是否受到影响。
  2. 如果您受到影响,请迁移到受支持的替代方案。

确定您是否受到影响

查看您的 OAuth 客户端 ID 类型

前往 Google API Console 的 Credentials page ,并在 OAuth 2.0 客户端 ID 部分下查看您的 OAuth 客户端 ID 类型。可以是以下任何一项:Web 应用AndroidiOS通用 Windows 平台 (UWP)Chrome 应用电视和受限输入设备桌面应用

如果您的客户端类型是 Android、Chrome 应用或 iOS,并且您使用的是环回 IP 地址流,请继续执行下一步。

如果您在桌面应用 OAuth 客户端上使用环回 IP 地址流程,则无需执行与此弃用有关的任何操作,因为 Google 将继续支持使用该 OAuth 客户端类型。

如何确定您的应用是否在使用环回 IP 地址流

检查您的应用代码传出网络调用(如果您的应用使用的是 OAuth 库),确定您的应用发出的 Google OAuth 授权请求是否正在使用环回重定向 URI 值。

检查应用代码

检查应用代码中调用 Google OAuth 授权端点的部分,确定 redirect_uri 参数是否具有以下任何值:
  • redirect_uri=http://127.0.0.1:<port> 例如 redirect_uri=http://127.0.0.1:3000
  • redirect_uri=http://[::1]:<port> 例如 redirect_uri=http://[::1]:3000
  • redirect_uri=http://localhost:<port> 例如 redirect_uri=http://localhost:3000
环回 IP 地址重定向流程请求示例如下所示:
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

检查去电网络通话

检查网络调用的方法因应用客户端类型而异。
检查网络调用时,请查找发送到 Google OAuth 授权端点的请求,并确定 redirect_uri 参数是否具有以下任何值:
  • redirect_uri=http://127.0.0.1:<port> 例如 redirect_uri=http://127.0.0.1:3000
  • redirect_uri=http://[::1]:<port> 例如 redirect_uri=http://[::1]:3000
  • redirect_uri=http://localhost:<port> 例如 redirect_uri=http://localhost:3000
环回 IP 地址重定向流请求示例如下所示:
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

迁移到受支持的替代方案

移动客户端 (Android / iOS)

如果您确定您的应用在 Android 或 iOS OAuth 客户端类型中使用环回 IP 地址流,则应改为使用 Google 登录移动 SDK(AndroidiOS)。

借助该 SDK,您可以轻松访问 Google API,并处理对 Google 的 OAuth 2.0 授权端点的所有调用。

以下文档链接介绍了如何在不使用环回 IP 地址重定向 URI 的情况下使用 Google 登录 SDK 访问 Google API。

访问 Google API (Android)

服务器端(离线)访问
以下示例展示了如何在 Android 设备上访问 Google API
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
  GoogleSignInAccount account = task.getResult(ApiException.class);
  
  // request a one-time authorization code that your server exchanges for an
  // access token and sometimes refresh token
  String authCode = account.getServerAuthCode();
  
  // Show signed-in UI
  updateUI(account);

  // TODO(developer): send code to server and exchange for access/refresh/ID tokens
} catch (ApiException e) {
  Log.w(TAG, "Sign-in failed", e);
  updateUI(null);
}

请参阅服务器端访问指南,了解如何从服务器端访问 Google API。

在 iOS 应用中访问 Google API

客户端访问

以下示例展示了如何在 iOS 设备上的客户端访问 Google API

user.authentication.do { authentication, error in
  guard error == nil else { return }
  guard let authentication = authentication else { return }
  
  // Get the access token to attach it to a REST or gRPC request.
  let accessToken = authentication.accessToken
  
  // Or, get an object that conforms to GTMFetcherAuthorizationProtocol for
  // use with GTMAppAuth and the Google APIs client library.
  let authorizer = authentication.fetcherAuthorizer()
}

使用访问令牌来调用 API,方法是在 REST 或 gRPC 请求的标头中添加访问令牌 (Authorization: Bearer ACCESS_TOKEN),或者将提取器授权程序 (GTMFetcherAuthorizationProtocol) 与 适用于 REST 的 Objective-C 客户端库搭配使用。

请参阅客户端访问指南,了解如何在客户端访问 Google API。 了解如何在客户端访问 Google API。

服务器端(离线)访问
以下示例展示了如何在服务器端访问 Google API 以支持 iOS 客户端。
GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
  guard error == nil else { return }
  guard let user = user else { return }
  
  // request a one-time authorization code that your server exchanges for
  // an access token and refresh token
  let authCode = user.serverAuthCode
}

请参阅服务器端访问指南,了解如何从服务器端访问 Google API。

Chrome 应用客户端

如果您确定您的应用在 Chrome 应用客户端上使用环回 IP 地址流,则应改用 Chrome Identity API

以下示例展示了如何在不使用环回 IP 地址重定向 URI 的情况下获取所有用户联系人。

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {

  
  // retrieve access token
  chrome.identity.getAuthToken({interactive: true}, function(token) {
  
  // ..........


  // the example below shows how to use a retrieved access token with an appropriate scope
  // to call the Google People API contactGroups.get endpoint

  fetch(
    'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=API_KEY',
    init)
    .then((response) => response.json())
    .then(function(data) {
      console.log(data)
    });
   });
 });
};

请参阅 Chrome Identity API 指南,详细了解如何通过 Chrome Identity API 访问用户身份和调用 Google 端点。