Руководство по миграции потока IP-адресов с обратной связью

Обзор

16 февраля 2022 года мы объявили о планах повысить безопасность взаимодействия с Google OAuth за счёт использования более безопасных потоков OAuth. Это руководство поможет вам разобраться в необходимых изменениях и шагах для успешного перехода от петлевого IP-адреса к поддерживаемым альтернативным вариантам.

Эта мера защиты от фишинга и атак с использованием имперсонации приложений при взаимодействии с конечными точками авторизации Google OAuth 2.0.

Что такое поток IP-адресов обратной связи?

Поток с использованием петлевого IP-адреса поддерживает использование петлевого IP-адреса или localhost в качестве компонента хоста URI перенаправления, куда отправляются учётные данные после одобрения пользователем запроса на согласие OAuth. Этот поток уязвим для атак типа «человек посередине» , когда вредоносное приложение, обращаясь к тому же петлевому интерфейсу в некоторых операционных системах, может перехватить ответ сервера авторизации на указанный URI перенаправления и получить доступ к коду авторизации.

Функция обратной связи по IP-адресу устарела для собственных клиентов OAuth для iOS, Android и Chrome, но будет по-прежнему поддерживаться в настольных приложениях.

Ключевые даты соответствия

  • 14 марта 2022 г. — новым клиентам OAuth запрещено использовать поток IP-адресов Loopback.
  • 1 августа 2022 г. — пользователю может быть показано предупреждающее сообщение в ответ на несоответствующие требованиям запросы OAuth.
  • 31 августа 2022 г. — поток IP-адресов Loopback заблокирован для собственных клиентов Android, приложений Chrome и iOS OAuth, созданных до 14 марта 2022 г.
  • 21 октября 2022 г. — все существующие клиенты заблокированы (включая исключенных клиентов)

В случае несоответствующих требованиям запросов пользователю будет показано сообщение об ошибке. Это сообщение будет сообщать пользователю о том, что приложение заблокировано, и одновременно отображать адрес электронной почты службы поддержки, указанный вами на экране согласия OAuth в консоли Google API .

Для завершения процесса миграции необходимо выполнить два основных шага:
  1. Определите, касается ли это вас.
  2. Если вас это коснулось, перейдите на поддерживаемую альтернативу.

Определите, затронуты ли вы

Проверьте тип идентификатора клиента OAuth.

Перейдите к Clients page принадлежащий Google Cloud Console и посмотрите тип вашего идентификатора клиента OAuth в разделе «Идентификаторы клиентов OAuth 2.0» . Это может быть любой из следующих вариантов: веб-приложение , Android , iOS , универсальная платформа Windows (UWP) , приложение Chrome , телевизоры и устройства с ограниченными возможностями ввода , настольное приложение .

Если ваш тип клиента — Android, Chrome app или iOS и вы используете поток IP-адресов обратной связи, перейдите к следующему шагу.

Вам не нужно предпринимать никаких действий, связанных с этим прекращением поддержки, если вы используете поток IP-адресов обратной связи в клиенте OAuth приложения для настольного компьютера, поскольку использование с этим типом клиента 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-адресов обратной связи с типом клиента OAuth для Android или iOS, вам следует перейти на использование рекомендуемых пакетов SDK ( Android , iOS ).

SDK упрощает доступ к API Google и обрабатывает все вызовы конечных точек авторизации Google OAuth 2.0.

Приведенные ниже ссылки на документацию содержат информацию о том, как использовать рекомендуемые SDK для доступа к API Google без использования URI перенаправления обратного IP-адреса.

Доступ к API Google на Android

Доступ на стороне клиента

В следующем примере показано, как получить доступ к API Google на стороне клиента на Android с помощью рекомендуемой библиотеки Android Identity Services.

  List requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA);
    AuthorizationRequest authorizationRequest = AuthorizationRequest.builder().setRequestedScopes(requestedScopes).build();
    Identity.getAuthorizationClient(activity)
            .authorize(authorizationRequest)
            .addOnSuccessListener(
                authorizationResult -> {
                  if (authorizationResult.hasResolution()) {
                    // Access needs to be granted by the user
                    PendingIntent pendingIntent = authorizationResult.getPendingIntent();
                    try {
    startIntentSenderForResult(pendingIntent.getIntentSender(),
    REQUEST_AUTHORIZE, null, 0, 0, 0, null);
                    } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage());
                    }
                  } else {
                    // Access already granted, continue with user action
                    saveToDriveAppFolder(authorizationResult);
                  }
                })
            .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));

Передайте authorizationResult заданному вами методу для сохранения содержимого в папке пользователя на диске. У authorizationResult есть метод getAccessToken() , который возвращает токен доступа.

Доступ на стороне сервера (офлайн)
В следующем примере показано, как получить доступ к API Google на стороне сервера Android.
  List requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA);
    AuthorizationRequest authorizationRequest = AuthorizationRequest.builder()
    .requestOfflineAccess(webClientId)
            .setRequestedScopes(requestedScopes)
            .build();
    Identity.getAuthorizationClient(activity)
            .authorize(authorizationRequest)
            .addOnSuccessListener(
                authorizationResult -> {
                  if (authorizationResult.hasResolution()) {
                    // Access needs to be granted by the user
                    PendingIntent pendingIntent = authorizationResult.getPendingIntent();
                    try {
    startIntentSenderForResult(pendingIntent.getIntentSender(),
    REQUEST_AUTHORIZE, null, 0, 0, 0, null);
                    } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage());
                    }
                  } else {
                    String authCode = authorizationResult.getServerAuthCode();
                  }
                })
            .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));

У authorizationResult есть метод getServerAuthCode() , который возвращает код авторизации, который вы можете отправить на свой бэкэнд для получения токена доступа и обновления.

Доступ к API Google в приложении iOS

Доступ на стороне клиента

В примере ниже показано, как получить доступ к API Google на стороне клиента на iOS .

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 ) с клиентской библиотекой API Google для Objective-C для REST .

Ознакомьтесь с руководством по доступу на стороне клиента о том, как получить доступ к API Google на стороне клиента. о том, как получить доступ к API Google на стороне клиента.

Доступ на стороне сервера (офлайн)
В примере ниже показано, как получить доступ к API Google на стороне сервера для поддержки клиента 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
}

Ознакомьтесь с руководством по доступу со стороны сервера, чтобы узнать, как получить доступ к API Google со стороны сервера.

Клиент приложения Chrome

Если вы определили, что ваше приложение использует петлевой поток IP-адресов на клиенте приложения Chrome, вам следует перейти на использование API Chrome Identity .

В примере ниже показано, как получить все контакты пользователя без использования URI перенаправления IP-адреса обратной связи.

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)
    });
   });
 });
};

Дополнительную информацию о том, как получить доступ к аутентификации пользователей и вызвать конечные точки Google с помощью API Chrome Identity, см. в руководстве по API Chrome Identity.