Обзор
16 февраля 2022 года мы объявили о планах сделать взаимодействие с Google OAuth более безопасным за счёт использования более безопасных потоков OAuth. Это руководство поможет вам разобраться в необходимых изменениях и шагах для успешного перехода с внеполосного (OOB) потока OAuth на поддерживаемые альтернативы.
Эта мера защиты от фишинга и атак с использованием имперсонации приложений при взаимодействии с конечными точками авторизации Google OAuth 2.0.
Что такое OOB?
OAuth out-of-band (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 г. — все существующие клиенты заблокированы (включая освобожденных клиентов)
В случае несоответствующих требованиям запросов пользователю будет показано сообщение об ошибке. Это сообщение будет сообщать пользователю о том, что приложение заблокировано, и одновременно отображать адрес электронной почты службы поддержки, указанный вами на экране согласия OAuth в консоли Google API .
- Определите, касается ли это вас.
- Если вас это коснулось, перейдите на более безопасную альтернативу.
Определите, затронуты ли вы
Это прекращение поддержки применимо только к производственным приложениям (т. е. приложениям со статусом публикации « В производстве» ). Этот процесс продолжит работать для приложений со статусом публикации «Тестирование» .
Проверьте статус вашей публикации в OAuth Branding pageпринадлежащий Google Cloud Console и перейдите к следующему шагу, если вы используете поток OOB в проекте со статусом публикации «В производстве».
Как определить, использует ли ваше приложение OOB-поток
Проверьте код вашего приложения или исходящий сетевой вызов (если ваше приложение использует библиотеку OAuth), чтобы определить, использует ли запрос авторизации Google OAuth, который делает ваше приложение, значение URI перенаправления OOB.
Проверьте код вашего приложения
redirect_uri
какие-либо из следующих значений:-
redirect_uri=urn:ietf:wg:oauth:2.0:oob
-
redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
-
redirect_uri=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>
Проверка исходящего сетевого вызова
- Веб-приложение — проверка сетевой активности в Chrome
- Android — проверка сетевого трафика с помощью Network Inspector
- Chrome-приложения
- Перейдите на страницу расширений Chrome.
- Установите флажок «Режим разработчика» в правом верхнем углу страницы расширения.
- Выберите расширение, которое вы хотите отслеживать
- Нажмите на ссылку фоновой страницы в разделе «Проверка представлений» на странице расширения.
- Откроется всплывающее окно «Инструменты разработчика» , где вы сможете отслеживать сетевой трафик на вкладке «Сеть».
- iOS — Анализ HTTP-трафика с помощью Instruments
- Универсальная платформа Windows (UWP) — проверка сетевого трафика в Visual Studio
- Приложения для настольных компьютеров — используйте инструмент захвата сетевого трафика, доступный для операционной системы, для которой разработано приложение.
redirect_uri
какие-либо из следующих значений:-
redirect_uri=urn:ietf:wg:oauth:2.0:oob
-
redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
-
redirect_uri=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 ( Android , iOS ).
SDK упрощает доступ к API Google и обрабатывает все вызовы конечных точек авторизации Google OAuth 2.0.
Приведенные ниже ссылки на документацию содержат информацию о том, как использовать рекомендуемые SDK для доступа к API Google без использования URI перенаправления OOB.
Доступ к API Google на Android
Доступ на стороне клиента
В следующем примере показано, как получить доступ к API Google на стороне клиента на Android с помощью рекомендуемой библиотеки Android Identity Services.
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
), либо используя авторизатор выборки ( 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
Если вы определили, что ваше приложение использует поток OOB на клиенте приложения Chrome, вам следует перейти на использование API Chrome Identity .
В примере ниже показано, как получить все контакты пользователя без использования 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) }); }); }); };
Дополнительную информацию о том, как получить доступ к аутентификации пользователей и вызвать конечные точки Google с помощью API Chrome Identity, см. в руководстве по API Chrome Identity.
Веб-приложение
Если вы определили, что ваше приложение использует OOB-поток для веб-приложений, вам следует перейти на одну из наших клиентских библиотек Google API. Клиентские библиотеки для различных языков программирования перечислены здесь .
Библиотеки упрощают доступ к API Google и обработку всех вызовов конечных точек Google.
Доступ на стороне сервера (офлайн)
- Подготовьте сервер и определите общедоступную конечную точку (URI перенаправления) для получения кода авторизации.
- Настройте URI перенаправления в Clients page принадлежащий Google Cloud Console
В приведенном ниже фрагменте кода показан пример NodeJS по использованию API Google Drive для вывода списка файлов пользователя Google Drive на стороне сервера без использования 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
) .