Обзор
16 февраля 2022 г. мы объявили о планах сделать взаимодействие с Google OAuth более безопасным за счет использования более защищенных потоков OAuth. В этом руководстве рассказывается, как перейти с обратной связи по IP-адресу на поддерживаемые альтернативные варианты.
Это защитная мера против фишинга и атак с имитацией приложений при взаимодействии с конечными точками авторизации OAuth 2.0 от Google.
Что такое поток IP-адресов обратной связи?
Процесс с использованием IP-адреса обратной связи позволяет использовать IP-адрес обратной связи или localhost в качестве компонента хоста URI перенаправления, на который отправляются учетные данные после того, как пользователь одобрит запрос согласия OAuth.
Этот процесс уязвим для атак посредника, когда вредоносное приложение, получающее доступ к тому же интерфейсу обратной связи в некоторых операционных системах, может перехватить ответ от сервера авторизации на заданный URI перенаправления и получить доступ к коду авторизации.
Процесс замыкания IP-адреса на себя больше не будет поддерживаться для приложений OAuth на iOS, Android и Chrome, но по-прежнему будет доступен для компьютерных приложений.
Ключевые даты
- 14 марта 2022 г. – новым клиентам OAuth запрещено использовать процесс с IP-адресом обратной связи.
- 1 августа 2022 г. – для запросов OAuth, не соответствующих требованиям, может показываться предупреждение.
- 31 августа 2022 г. – блокировка процесса замыкания IP-адреса на себя для клиентов OAuth Android, Chrome и iOS, созданных до 14 марта 2022 г.
- 21 октября 2022 г. – все существующие клиенты заблокированы (в том числе те, для которых были сделаны исключения).
Для запросов, не соответствующих требованиям, будет отображаться пользовательское сообщение об ошибке. В сообщении будет указано, что приложение заблокировано, а также будет показан адрес электронной почты службы поддержки, который вы зарегистрировали в окне запроса доступа OAuth в консоли Google Cloud.
Процесс переноса состоит из двух основных этапов:
- Определите, затронет ли вас это изменение.
- Если вы используете этот метод, перейдите на поддерживаемую альтернативу.
Как определить, затронет ли вас это изменение
Проверьте тип приложения OAuth
Перейдите на страницу клиентов в Google Cloud Console и посмотрите тип приложения OAuth в разделе Идентификаторы клиентов OAuth 2.0. Это может быть Веб-приложение, Android, iOS, Универсальная платформа Windows (UWP), Приложение Chrome, Телевизоры и устройства с ограниченным вводом или Приложение для компьютеров.
Если у вас приложение для Android, Chrome или 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>
Проверка исходящего сетевого вызова
Способ проверки сетевых вызовов зависит от типа приложения.
- Веб-приложение – проверьте сетевую активность в Chrome.
- Android – проверка сетевого трафика с помощью Network Inspector.
- Приложения Chrome
- Перейдите на страницу расширений Chrome.
- Установите флажок Режим разработчика в правом верхнем углу страницы расширений.
- Выберите расширение, которое хотите отслеживать.
- Нажмите на ссылку фоновая страница в разделе Проверить просмотры на странице расширения.
- Откроется диалоговое окно Инструменты разработчика, в котором вы сможете отслеживать сетевой трафик на вкладке Сеть.
- iOS – Анализ HTTP-трафика с помощью Instruments
- Компьютерные приложения. Используйте инструмент для записи сетевого трафика, доступный для операционной системы, для которой разработано приложение.
При проверке сетевых вызовов ищите запросы, отправленные на конечные точки авторизации 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 и обрабатывает все вызовы конечных точек авторизации OAuth 2.0.
По ссылкам на документы ниже вы найдете информацию о том, как использовать рекомендуемые SDK для доступа к API Google без URI перенаправления с IP-адресом обратной связи.
Доступ к API Google на Android
Клиентский доступ
В примере ниже показано, как получить доступ к API Google на стороне клиента в Android с помощью рекомендуемой библиотеки сервисов идентификации Google для Android.
List<Scopes> 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<Scopes> 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 <var>ACCESS_TOKEN</var>) или используя авторизатор средства извлечения (GTMFetcherAuthorizationProtocol) с клиентской библиотекой API Google для Objective-C для 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, перейдите на Chrome Identity API.
В примере ниже показано, как получить все контакты пользователя без использования URI перенаправления с IP-адресом обратной связи.
window.onload = function() { document.querySelector('button').addEventListener('click', function() { // retrieve access token chrome.identity.getAuthToken({interactive: true}, function(token) { // .......... // the following example 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 с помощью Chrome Identity API, можно найти в руководстве по Chrome Identity API.