總覽
我們在 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 同意畫面中註冊的支援電子郵件。
- 判斷您是否受到影響。
- 如果受到影響,請改用支援的替代方案。
判斷您是否受到影響
查看您的 OAuth 用戶端 ID 類型
前往 Google API Console 的 Credentials page ,並在「OAuth 2.0 用戶端 ID」部分下方查看您的 OAuth 用戶端 ID 類型。可以是下列任一項目:網頁應用程式、Android、iOS、通用 Windows 平台 (UWP)、Chrome 應用程式、電視與受限輸入裝置、電腦版應用程式。
如果您的用戶端類型是 Android、Chrome 應用程式或 iOS,且您正在使用回送 IP 位址流程,請繼續進行下一個步驟。
如果您在電腦版應用程式 OAuth 用戶端上使用回送 IP 位址流程,則系統將繼續支援使用該 OAuth 用戶端類型的情況,因此您無須採取任何行動。
如何判斷應用程式是否使用回送 IP 位址流程
請檢查應用程式程式碼或傳出網路呼叫 (如果應用程式使用 OAuth 程式庫),判斷應用程式是否使用回送重新導向 URI 值。
檢查應用程式程式碼
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
https://accounts.google.com/o/oauth2/v2/auth? redirect_uri=http://localhost:3000& response_type=code& scope=<SCOPES>& state=<STATE>& client_id=<CLIENT_ID>
檢查撥出網路通話
- 網頁應用程式 - 檢查 Chrome 的網路活動
- Android - 使用網路檢查器檢查網路流量
-
Chrome 應用程式
- 前往 Chrome 擴充功能頁面
- 勾選擴充功能頁面右上角的「開發人員模式」核取方塊
- 選取要監控的擴充功能
- 在擴充功能頁面的「檢查檢視畫面」部分中,按一下「背景頁面」連結
- 系統會開啟「開發人員工具」彈出式視窗,供您監控 「網路」分頁中的網路流量。
- iOS: 使用檢測設備分析 HTTP 流量
- 通用 Windows 平台 (UWP) - 在 Visual Studio 中檢查網路流量
- 電腦應用程式 - 使用適用於開發應用程式作業系統的作業系統的網路擷取工具
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
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 登入 Mobile SDK (Android、iOS)。
這個 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-C 適用的 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 指南。