Руководство по миграции внеполосного (OOB) потока

Обзор

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

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

Что такое ООБ?

Внеполосный OAuth (OOB) , также называемый ручным копированием/вставкой, представляет собой устаревший поток, разработанный для поддержки собственных клиентов, у которых нет URI перенаправления для принятия учетных данных после того, как пользователь одобрит запрос на согласие OAuth. Поток OOB представляет собой риск удаленного фишинга, и клиенты должны перейти на альтернативный метод для защиты от этой уязвимости.

Поток OOB устарел для всех типов клиентов, т. е. веб-приложений, Android, iOS, универсальной платформы Windows (UWP), приложений Chrome, телевизоров и устройств с ограниченным вводом, настольных приложений.

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

  • 28 февраля 2022 г. — новое использование OAuth заблокировано для потока OOB.
  • 5 сентября 2022 г. — для несоответствующих запросов OAuth может отображаться предупреждающее сообщение для пользователя.
  • 3 октября 2022 г. — поток OOB устарел для клиентов OAuth, созданных до 28 февраля 2022 г.
  • 31 января 2023 г. — все существующие клиенты заблокированы (включая исключенных клиентов). Клиенты могут запросить единовременное продление для продолжения использования потока OOB до 31 января 2023 года, как указано в сообщении электронной почты, отправленном затронутым клиентам.

Предупреждающее сообщение для пользователя может отображаться для несоответствующих запросов за месяц до того, как, например, 5 сентября 2022 г., поток OOB полностью устарел. Сообщение будет информировать пользователей о том, что приложение может быть заблокировано в ближайшее время, при отображении электронного письма поддержки, которое вы зарегистрировали на экране согласия OAuth в Google API Console .

Вы можете подтвердить предупреждающее сообщение для пользователя и подавить его, передав параметр запроса в вызове авторизации, как показано ниже:
  • Перейдите к коду в своем приложении, где вы отправляете запросы к конечной точке авторизации Google OAuth 2.0 .
  • Добавьте параметр ack_oob_shutdown со значением даты вступления в силу: 2022-10-03 в запрос потока перенаправления. Пример:
    ack_oob_shutdown=2022-10-03
Существует два основных шага для завершения процесса миграции:
  1. Определите, затронуты ли вы.
  2. Перейдите на более безопасную альтернативу, если вы пострадали.

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

Это прекращение поддержки применимо только к производственным приложениям (т. е. приложениям со статусом публикации, установленным на В производстве . Поток будет продолжать работать для приложений со статусом публикации Тестирование .

Проверьте свой статус публикации в OAuth Consent Screen pageили Google API Console и перейдите к следующему шагу, если вы используете поток OOB в проекте со статусом публикации «В производстве».

Как определить, использует ли ваше приложение поток OOB

Проверьте код своего приложения или исходящий сетевой вызов (если ваше приложение использует библиотеку OAuth), чтобы определить, использует ли запрос авторизации Google OAuth, который делает ваше приложение, значение URI перенаправления OOB.

Проверьте код вашего приложения

Просмотрите раздел кода вашего приложения, в котором вы совершаете вызовы к конечным точкам авторизации Google OAuth, и определите, имеет ли параметр redirect_uri какое-либо из следующих значений:
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
Пример запроса потока перенаправления OOB будет выглядеть следующим образом:
https://accounts.google.com/o/oauth2/v2/auth?
response_type=code&
scope=<SCOPES>&
state=<STATE>&
redirect_uri=urn:ietf:wg:oauth:2.0:oob&
client_id=<CLIENT_ID>

Проверка исходящего сетевого вызова

Способ проверки сетевых вызовов зависит от типа клиента вашего приложения.
При проверке сетевых вызовов найдите запросы, отправленные на конечные точки авторизации Google OAuth, и определите, имеет ли параметр redirect_uri одно из следующих значений:
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
Пример запроса потока перенаправления OOB будет выглядеть следующим образом:
https://accounts.google.com/o/oauth2/v2/auth?
response_type=code&
scope=<SCOPES>&
state=<STATE>&
redirect_uri=urn:ietf:wg:oauth:2.0:oob&
client_id=<CLIENT_ID>

Переход на безопасную альтернативу

Мобильные клиенты (Android/iOS)

Если вы определили, что ваше приложение использует поток OOB с типом клиента OAuth для Android или iOS, вам следует перейти на использование наших мобильных SDK для входа в Google ( Android , iOS ).

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

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

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

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

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

Доступ к 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 . для ОТДЫХА .

Ознакомьтесь с руководством по доступу на стороне клиента, чтобы узнать, как получить доступ к 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

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

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

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.

Веб приложение

Если вы определили, что ваше приложение использует поток OOB для веб-приложения, вам следует перейти на использование одной из наших клиентских библиотек API Google. Здесь перечислены клиентские библиотеки для разных языков программирования.

Библиотеки упрощают доступ к API Google и обрабатывают все вызовы к конечным точкам Google.

Серверный (автономный) доступ
Режим доступа на стороне сервера (автономный) требует, чтобы вы сделали следующее:
  • Включите сервер и определите общедоступную конечную точку (URI перенаправления) для получения кода авторизации.
  • Настройте URI перенаправления в Credentials page Google API Console.

В приведенном ниже фрагменте кода показан пример NodeJS, использующий API Google Диска для вывода списка файлов Google Диска пользователя на стороне сервера без использования URI перенаправления OOB.

async function main() {
  const server = http.createServer(async function (req, res) {

  if (req.url.startsWith('/oauth2callback')) {
    let q = url.parse(req.url, true).query;

    if (q.error) {
      console.log('Error:' + q.error);
    } else {
      
      // Get access and refresh tokens (if access_type is offline)
      let { tokens } = await oauth2Client.getToken(q.code);
      oauth2Client.setCredentials(tokens);

      // Example of using Google Drive API to list filenames in user's Drive.
      const drive = google.drive('v3');
      drive.files.list({
        auth: oauth2Client,
        pageSize: 10,
        fields: 'nextPageToken, files(id, name)',
      }, (err1, res1) => {
        // TODO(developer): Handle response / error.
      });
    }
  }
}

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

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

В приведенном ниже фрагменте кода на языке JavaScript показан пример использования API Google для доступа к событиям календаря пользователя на стороне клиента.


// initTokenClient() initializes a new token client with your
// web app's client ID and the scope you need access to

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  
  // callback function to handle the token response
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) { 
      gapi.client.setApiKey('YOUR_API_KEY');
      gapi.client.load('calendar', 'v3', listUpcomingEvents);
    }
  },
});

function listUpcomingEvents() {
  gapi.client.calendar.events.list(...);
}

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

Настольный клиент

Если вы определили, что ваше приложение использует поток OOB на настольном клиенте, вам следует перейти на использование потока IP-адреса замыкания на себя ( localhost или 127.0.0.1 ) .