總覽
我們在 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 應用程式、TV 和有限輸入裝置、電腦版應用程式。
如果您的用戶端類型為 Android、Chrome 應用程式或 iOS,且您使用的是回送 IP 位址流程,請繼續下一個步驟。
如果您在電腦版應用程式 OAuth 用戶端上使用回送 IP 位址流程,則不必採取任何行動,因為系統會繼續支援該 OAuth 用戶端類型的使用情況。
如何判斷應用程式是否使用回送 IP 位址流程
檢查應用程式程式碼或傳出網路呼叫 (如果應用程式使用 OAuth 程式庫),判斷應用程式發出的 Google 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)
如果您判斷應用程式使用回送 IP 位址流程,搭配 Android 或 iOS OAuth 用戶端類型,則應改用 Google 登入行動 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 適用的 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 指南。