概要
2022 年 2 月 16 日、Google はより安全な OAuth フローを使用して、Google OAuth インタラクションをより安全にする計画を 発表しました。このガイドでは、ループバック IP アドレスのフローからサポートされている代替アドレスに移行するために必要な変更と手順について説明します。
この取り組みは、Google の OAuth 2.0 認可エンドポイントとのやり取りにおけるフィッシング攻撃やアプリのなりすまし攻撃を防ぐための対策です。
ループバック IP アドレスのフローとは
ループバック IP アドレスのフローでは、ユーザーが OAuth 同意リクエストを承認した後、認証情報が送信されるリダイレクト URI のホスト コンポーネントとして、ループバック IP アドレスまたはlocalhost
を使用できます。このフローは中間者攻撃に対して脆弱で、悪意のあるアプリが一部のオペレーティング システムの同じループバック インターフェースにアクセスすると、認可サーバーから指定されたリダイレクト URI へのレスポンスが傍受されて、認可コードにアクセスするおそれがあります。
ループバック IP アドレス フローは、iOS、Android、Chrome の OAuth ネイティブ クライアント タイプで非推奨となっていますが、デスクトップ アプリでは引き続きサポートされます。
主な準拠日
- 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 Console の OAuth 同意画面で登録したサポートメールアドレスが表示されます。
- 影響を受けているかどうかを確認します。
- 影響を受ける場合は、サポートされている代替手段に移行してください。
影響を受けているかどうかを確認する
OAuth クライアント ID のタイプを確認する
Google API Console の Credentials page に移動し、[OAuth 2.0 クライアント ID] セクションで OAuth クライアント ID タイプを表示します。ウェブアプリ、Android、iOS、Universal Windows Platform(UWP)、Chrome アプリ、テレビと入力制限のあるデバイス、デスクトップ アプリのいずれかになります。
クライアントの種類が 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 - Network Inspector を使用してネットワーク トラフィックを検査する
-
Chrome アプリ
- Chrome 拡張機能ページに移動
- 拡張機能ページの右上にある [デベロッパー モード] チェックボックスをオンにします。
- モニタリングする拡張機能を選択する
- 拡張機能ページの [ビューを検査する] セクションで [バックグラウンド ページ] リンクをクリックします。
- デベロッパー ツールのポップアップが開き、 [ネットワーク] タブでネットワーク トラフィックをモニタリングできます。
- iOS - Instruments を使用した HTTP トラフィックの分析
- Universal Windows Platform(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 ログイン モバイル 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
)、または
Objective-C for REST 用 Google API クライアント ライブラリでフェッチャー承認ツール(GTMFetcherAuthorizationProtocol
)を使用します。
クライアントサイドで 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 ガイドをご覧ください。