Обзор
16 февраля 2022 года мы объявили о планах сделать взаимодействие с Google OAuth более безопасным за счет использования более защищенных потоков OAuth. Это руководство поможет вам понять необходимые изменения и шаги для успешного перехода от потока с использованием IP-адреса замыкания на землю к поддерживаемым альтернативам.
Эти меры направлены на защиту от фишинговых атак и атак с использованием поддельных приложений при взаимодействии с точками авторизации Google OAuth 2.0.
Что такое поток IP-адреса обратной связи?
Использование IP-адреса замыкающей петли (loopback IP address) позволяет использовать IP-адрес замыкающей петли илиlocalhost в качестве хост-компонента URI перенаправления, куда отправляются учетные данные после того, как пользователь подтвердит запрос на согласие OAuth. Этот поток уязвим для атак типа « человек посередине », когда вредоносное приложение, обращающееся к тому же интерфейсу замыкающей петли в некоторых операционных системах, может перехватить ответ от сервера авторизации на заданный URI перенаправления и получить доступ к коду авторизации.Использование IP-адреса обратной связи для нативных клиентов OAuth в iOS, Android и Chrome прекращается, но будет по-прежнему поддерживаться в настольных приложениях.
Ключевые сроки соблюдения требований
- 14 марта 2022 г. — новым клиентам OAuth заблокирован доступ к потоку IP-адресов Loopback.
- 1 августа 2022 г. — для запросов OAuth, не соответствующих требованиям, может отображаться предупреждающее сообщение, видимое пользователю.
- 31 августа 2022 г. — блокировка потока IP-адресов Loopback для нативных клиентов OAuth Android, Chrome и iOS, созданных до 14 марта 2022 г.
- 21 октября 2022 г. - все существующие клиенты заблокированы (включая клиентов, на которых распространяется исключение).
При несоответствии запросам пользователю будет отображаться сообщение об ошибке. В сообщении будет указано, что приложение заблокировано, при этом будет отображаться адрес электронной почты службы поддержки, указанный в настройках согласия OAuth в консоли Google API .
- Определите, затрагивает ли это вас.
- Если вас это затронуло, перейдите на поддерживаемую альтернативную платформу.
Определите, затрагивает ли это вас.
Проверьте тип идентификатора клиента OAuth.
Перейдите на страницу «Клиенты» в консоли Google Cloud и найдите свой тип идентификатора клиента OAuth в разделе « Идентификаторы клиентов OAuth 2.0» . Это может быть один из следующих типов: веб-приложение , Android , iOS , универсальная платформа Windows (UWP) , приложение Chrome , телевизоры и устройства с ограниченным вводом , настольное приложение .
Перейдите к следующему шагу, если вы используете Android, приложение Chrome или iOS и применяете протокол с использованием IP-адреса замыкания (loopback IP address).
Если вы используете поток аутентификации по IP-адресу замыкания на землю в клиенте OAuth настольного приложения, вам не нужно ничего делать в связи с этим прекращением поддержки, поскольку использование с этим типом клиента 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 — анализ HTTP-трафика с помощью Instruments
- Для настольных приложений используйте инструмент захвата сетевого трафика, доступный для операционной системы, для которой было разработано приложение.
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-адресу локальной сети с клиентом OAuth для Android или iOS, вам следует перейти на использование рекомендуемых SDK ( Android , iOS ).
SDK упрощает доступ к API Google и обрабатывает все вызовы к конечным точкам авторизации Google OAuth 2.0.
Приведенные ниже ссылки на документацию содержат информацию о том, как использовать рекомендуемые SDK для доступа к API Google без использования URI перенаправления по IP-адресу локальной сети.
Доступ к API Google на Android
Доступ со стороны клиента
В следующем примере показано, как получить доступ к API Google на стороне клиента на Android, используя рекомендуемую библиотеку Google Identity Services для Android.
ListrequestedScopes = 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.ListrequestedScopes = 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 ), либо используя авторизатор fetcher ( GTMFetcherAuthorizationProtocol ) с клиентской библиотекой Google APIs для Objective-C for REST .
Ознакомьтесь с руководством по доступу на стороне клиента , чтобы узнать, как получить доступ к 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) }); }); }); };
Для получения дополнительной информации о том, как получить доступ к API Chrome Identity для аутентификации пользователей и вызывать конечные точки Google с помощью API Chrome Identity, ознакомьтесь с руководством .