回送 IP 位址流程遷移指南

總覽

我們在 2022 年 2 月 16 日 宣布計畫,採用更安全的 OAuth 流程,讓 Google OAuth 互動更加安全。本指南可協助您瞭解必要的變更,以及如何從回送 IP 位址流程成功遷移至支援的替代方案。

這項防護措施可有效防範網路釣魚和應用程式假冒攻擊,避免您與 Google 的 OAuth 2.0 授權端點互動。

什麼是回送 IP 位址流程?

回送 IP 位址流程支援使用回送 IP 位址或 localhost 當做重新導向 URI 的主機元件,在使用者核准 OAuth 同意要求後,會將憑證傳送至這個主機。且在���中間人」的���擊中,如果惡意應用程式在某些作業系統中存取相同回送介面,就可能攔截來自授權伺服器對指定重新導向 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 類型。其為以下任一種:網頁應用程式AndroidiOS通用 Windows 平台 (UWP)Chrome 應用程式TV 和有限輸入裝置電腦版應用程式

如果您的用戶端類型為 Android、Chrome 應用程式或 iOS,且您使用的是回送 IP 位址流程,請繼續下一個步驟。

如果您在電腦版應用程式 OAuth 用戶端上使用回送 IP 位址流程,則不���採取任何行動,因為系統會繼續支援該 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)

如果您判斷應用程式使用回送 IP 位址流程,搭配 Android 或 iOS OAuth 用戶端類型,則應改用 Google 登入行動 SDK (AndroidiOS)。

這個 SDK 可讓您輕鬆存取 Google API,並處理所有對 Google OAuth 2.0 授權端點的呼叫。

以下說明文件連結將說明如何在不使用回送 IP 位址重新導向 URI 的情況下,使用 Google 登入 SDK 存取 Google API。

在 Android 裝置上存取 Google API

伺服器端 (離線) 存取
以下範例說明如何在 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 適用的 Google API 用戶端程式庫

請參閱用戶端存取權指南,瞭解如何在用戶端存取 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 呼叫 Google 端點,請參閱 Chrome Identity API 指南