OAuth 2.0 для iOS и настольных приложений

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

OAuth 2.0 позволяет пользователям обмениваться определенными данными с приложением, сохраняя при этом конфиденциальность своих имен пользователей, паролей и другой информации. Например, приложение может использовать OAuth 2.0 для получения разрешения от пользователей на хранение файлов в их Google Дисках.

Установленные приложения распространяются на отдельные устройства, и предполагается, что эти приложения не могут хранить секреты. Они могут получать доступ к API Google, пока пользователь находится в приложении или когда приложение работает в фоновом режиме.

Этот процесс авторизации аналогичен тому, который используется для веб-серверных приложений . Главное отличие заключается в том, что установленные приложения должны открыть системный браузер и указать локальный URI перенаправления для обработки ответов от сервера авторизации Google.

Библиотеки и образцы

Для iOS-приложений мы рекомендуем использовать последнюю версию SDK Sign In With Google iOS . Этот SDK обрабатывает авторизацию пользователей и проще в реализации, чем низкоуровневый протокол, описанный в этом руководстве.

Для приложений, работающих на устройствах, не поддерживающих системный браузер или имеющих ограниченные возможности ввода, таких как телевизоры, игровые приставки, камеры или принтеры, см. OAuth 2.0 для телевизоров и устройств или Вход в систему на телевизорах и устройствах с ограниченными возможностями ввода .

Предварительные требования

Включите API для вашего проекта

Любое приложение, использующее API Google, должно включить эти API в консоли API.

Чтобы включить API для вашего проекта:

  1. Откройте библиотеку API в консоли Google API.
  2. При появлении запроса выберите проект или создайте новый.
  3. В библиотеке API перечислены все доступные API, сгруппированные по семействам продуктов и популярности. Если нужный вам API отсутствует в списке, воспользуйтесь поиском, чтобы найти его, или нажмите «Показать все» в семействе продуктов, к которому он относится.
  4. Выберите API, который хотите включить, затем нажмите кнопку «Включить» .
  5. При появлении запроса включите оплату.
  6. При появлении запроса ознакомьтесь с условиями использования API и примите их.

Создать учетные данные авторизации

Любое приложение, использующее OAuth 2.0 для доступа к API Google, должно иметь учетные данные авторизации, идентифицирующие приложение для сервера OAuth 2.0 Google. Следующие шаги описывают, как создать учетные данные для вашего проекта. Затем ваши приложения смогут использовать эти учетные данные для доступа к API, которые вы включили для этого проекта.

  1. Перейдите на страницу «Клиенты» .
  2. Нажмите «Создать клиента» .
  3. В следующих разделах описаны типы клиентов, поддерживаемые сервером авторизации Google. Выберите рекомендуемый для вашего приложения тип клиента, назовите свой OAuth-клиент и заполните остальные поля формы соответствующим образом.
iOS
  1. Выберите тип приложения для iOS .
  2. Введите имя для клиента OAuth. Это имя будет отображаться на странице «Клиенты» вашего проекта для идентификации клиента.
  3. Введите идентификатор пакета для вашего приложения. Идентификатор пакета — это значение ключа CFBundleIdentifier в файле ресурсов списка свойств информации вашего приложения ( info.plist ). Чаще всего это значение отображается в панели «Общие» или в панели «Подписание и возможности» редактора проекта Xcode. Идентификатор пакета также отображается в разделе «Общая информация» на странице информации о приложении на сайте Apple App Store Connect .

    Убедитесь, что вы используете правильный идентификатор пакета для вашего приложения, так как изменить его при использовании функции проверки приложения будет невозможно.

  4. (Необязательный)

    Если приложение опубликовано в App Store от Apple, введите его идентификатор (App Store ID). Идентификатор магазина — это числовая строка, которая присутствует в каждом URL-адресе App Store от Apple.

    1. Откройте приложение Apple App Store на своем устройстве iOS или iPadOS.
    2. Найдите своё приложение.
    3. Нажмите кнопку «Поделиться» (квадрат и символ стрелки вверх).
    4. Выберите «Копировать ссылку» .
    5. Вставьте ссылку в текстовый редактор. Идентификатор App Store — это последняя часть URL-адреса.

      Пример: https://apps.apple.com/app/google/id 284815942

  5. (Необязательный)

    Введите свой идентификатор команды. Дополнительную информацию см. в разделе « Как найти свой идентификатор команды» в документации по учетной записи разработчика Apple.

    Примечание: Поле «Идентификатор команды» обязательно для заполнения, если вы включаете проверку приложений для своего клиента.
  6. (Необязательный)

    Включите проверку приложений (App Check) для вашего iOS-приложения. При включении проверки приложений используется служба App Attest от Apple для проверки подлинности запросов OAuth 2.0, исходящих от вашего OAuth-клиента, и подтверждения того, что они поступают от вашего приложения. Это помогает снизить риск подмены приложения. Узнайте больше о включении проверки приложений для вашего iOS-приложения .

  7. Нажмите «Создать» .
UWP
  1. Выберите тип приложения «Универсальная платформа Windows» .
  2. Введите имя для клиента OAuth. Это имя будет отображаться в вашем проекте. идентифицировать клиента.
  3. Введите 12-символьный идентификатор вашего приложения в Microsoft Store. Это значение можно найти в Центре партнеров Microsoft на странице «Идентификация приложения» в разделе «Управление приложениями».
  4. Нажмите «Создать» .

Для приложений UWP URI перенаправления формируется с использованием уникального идентификатора безопасности пакета (SID) вашего приложения. Вы можете найти Package SID вашего приложения в файле Package.appxmanifest в вашем проекте Visual Studio.

При создании идентификатора клиента в консоли Google Cloud необходимо указать URI перенаправления в следующем формате, используя значение SID пакета в нижнем регистре:

ms-app://YOUR_APP_PACKAGE_SID

Для приложений UWP длина пользовательского URI не может превышать 39 символов, как указано в документации Microsoft .

Определите области доступа

Области доступа (scopes) позволяют вашему приложению запрашивать доступ только к тем ресурсам, которые ему необходимы, а также дают пользователям возможность контролировать объем предоставляемого ими доступа. Таким образом, может существовать обратная зависимость между количеством запрашиваемых областей доступа и вероятностью получения согласия пользователя.

Прежде чем приступать к внедрению авторизации OAuth 2.0, мы рекомендуем определить области доступа, к которым вашему приложению потребуются разрешения.

В документе «Области действия API OAuth 2.0» содержится полный список областей действия, которые вы можете использовать для доступа к API Google.

Получение токенов доступа OAuth 2.0

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

Шаг 1: Сгенерируйте средство проверки кода и запрос на проверку.

Google поддерживает протокол Proof Key for Code Exchange (PKCE), чтобы сделать процесс установки приложения более безопасным. Для каждого запроса на авторизацию создается уникальный верификатор кода, и его преобразованное значение, называемое "code_challenge", отправляется на сервер авторизации для получения кода авторизации.

Создайте средство проверки кода.

code_verifier — это высокоэнтропийная криптографическая случайная строка, использующая незарезервированные символы [AZ] / [az] / [0-9] / "-" / "." / "_" / "~", с минимальной длиной 43 символа и максимальной длиной 128 символов.

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

Задание «Создай код»

Поддерживаются два метода создания задания по программированию.

Методы генерации заданий по программированию
S256 (рекомендуется) В качестве проверки кода используется закодированный в Base64URL (без дополнения) хеш SHA256 верификатора кода.
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
простой Значение параметра проверки кода совпадает со значением, сгенерированным выше.
code_challenge = code_verifier

Шаг 2: Отправьте запрос на сервер Google OAuth 2.0.

Для получения авторизации пользователя отправьте запрос на сервер авторизации Google по адресу https://accounts.google.com/o/oauth2/v2/auth . Эта конечная точка обрабатывает поиск активной сессии, аутентифицирует пользователя и получает его согласие. Доступ к конечной точке возможен только по протоколу SSL, и она отклоняет HTTP-соединения (без SSL).

Сервер авторизации поддерживает следующие параметры строки запроса для установленных приложений:

Параметры
client_id Необходимый

Идентификатор клиента для вашего приложения. Это значение можно найти на странице «Клиенты» в консоли Cloud.

redirect_uri Необходимый

Определяет, как сервер авторизации Google отправляет ответ вашему приложению. Для установленных приложений доступно несколько вариантов перенаправления, и вам необходимо настроить учетные данные авторизации , выбрав конкретный метод перенаправления.

Значение должно точно совпадать с одним из разрешенных URI перенаправления для клиента OAuth 2.0, которые вы настроили на странице «Клиенты» в Cloud Console. Если это значение не совпадает с разрешенным URI, вы получите ошибку redirect_uri_mismatch .

В таблице указано соответствующее значение параметра redirect_uri для каждого метода:

значения redirect_uri
Пользовательская схема URI com.example.app : redirect_uri_path

или

com.googleusercontent.apps.123 : redirect_uri_path
  • com.example.app — это обратное DNS-обозначение домена, находящегося под вашим контролем. Для корректной работы пользовательская схема должна содержать точку.
  • com.googleusercontent.apps.123 — это обратное DNS-обозначение идентификатора клиента.
  • redirect_uri_path — это необязательный компонент пути, например, /oauth2redirect . Обратите внимание, что путь должен начинаться с одной косой черты, что отличается от обычных HTTP-URL.
IP-адрес обратной связи http://127.0.0.1: port или http://[::1]: port

Запросите у своей платформы соответствующий IP-адрес замыкания (loopback) и запустите HTTP-слушатель на случайном доступном порту. Замените port на фактический номер порта, на котором работает ваше приложение.

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

response_type Необходимый

Определяет, возвращает ли конечная точка Google OAuth 2.0 код авторизации.

Установите значение параметра равным code для установленных приложений.

scope Необходимый

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

Области доступа (scopes) позволяют вашему приложению запрашивать доступ только к тем ресурсам, которые ему необходимы, а также дают пользователям возможность контролировать объем предоставляемого ими доступа. Таким образом, существует обратная зависимость между количеством запрашиваемых областей доступа и вероятностью получения согласия пользователя.

code_challenge Рекомендуется

Указывает закодированный code_verifier , который будет использоваться в качестве серверного запроса при обмене кодами авторизации. Дополнительную информацию см. в разделе «Создание запроса кода» .

code_challenge_method Рекомендуется

Указывает, какой метод использовался для кодирования code_verifier , который будет применяться при обмене кодами авторизации. Этот параметр необходимо использовать вместе с параметром code_challenge . Значение code_challenge_method по умолчанию равно plain , если оно отсутствует в запросе, содержащем code_challenge . Единственными поддерживаемыми значениями для этого параметра являются S256 или plain .

state Рекомендуется

Указывает любое строковое значение, которое ваше приложение использует для поддержания состояния между вашим запросом на авторизацию и ответом сервера авторизации. Сервер возвращает точное значение, которое вы отправляете в виде пары name=value в идентификаторе фрагмента URL ( # ) redirect_uri после того, как пользователь дает согласие или отклоняет запрос на доступ вашего приложения.

Этот параметр можно использовать для различных целей, например, для перенаправления пользователя на правильный ресурс в вашем приложении, отправки одноразовых чисел (nonce) и предотвращения подделки межсайтовых запросов (CSS). Поскольку ваш redirect_uri может быть угадан, использование значения state может повысить вашу уверенность в том, что входящее соединение является результатом запроса аутентификации. Если вы сгенерируете случайную строку или закодируете хеш cookie или другое значение, которое отражает состояние клиента, вы можете проверить ответ, чтобы дополнительно убедиться, что запрос и ответ были отправлены из одного и того же браузера, обеспечивая защиту от таких атак, как подделка межсайтовых запросов . Пример создания и подтверждения токена state см. в документации OpenID Connect.

login_hint Необязательный

Если ваше приложение знает, какой пользователь пытается пройти аутентификацию, оно может использовать этот параметр для предоставления подсказки серверу аутентификации Google. Сервер использует эту подсказку для упрощения процесса входа в систему, либо предварительно заполняя поле электронной почты в форме входа, либо выбирая соответствующую сессию с несколькими учетными записями.

Установите значение параметра равным адресу электронной почты или sub , эквивалентному идентификатору пользователя в Google.

Примеры URL-адресов авторизации

На вкладках ниже представлены примеры URL-адресов авторизации для различных вариантов URI перенаправления.

URL-адреса идентичны, за исключением значения параметра redirect_uri . URL-адреса также содержат обязательные параметры response_type и client_id , а также необязательный параметр state . Каждый URL-адрес содержит переносы строк и пробелы для удобства чтения.

Пользовательская схема URI

https://accounts.google.com/o/oauth2/v2/auth?
 scope=email%20profile&
 response_type=code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken&
 redirect_uri=com.example.app%3A/oauth2redirect&
 client_id=client_id

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

https://accounts.google.com/o/oauth2/v2/auth?
 scope=email%20profile&
 response_type=code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken&
 redirect_uri=http%3A//127.0.0.1%3A9004&
 client_id=client_id

Шаг 3: Google запрашивает у пользователя согласие.

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

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

Ошибки

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

admin_policy_enforced

Учетная запись Google не может авторизовать одну или несколько запрошенных областей доступа из-за политики администратора Google Workspace. Дополнительную информацию о том, как администратор может ограничить доступ ко всем областям доступа или к конфиденциальным и ограниченным областям доступа до тех пор, пока доступ не будет явно предоставлен вашему идентификатору клиента OAuth, см. в справочной статье «Управление доступом сторонних и внутренних приложений к данным Google Workspace» .

disallowed_useragent

Точка авторизации отображается внутри встроенного пользовательского агента, что запрещено политикой Google OAuth 2.0 .

Разработчики iOS и macOS могут столкнуться с этой ошибкой при открытии запросов авторизации в WKWebView . Вместо этого разработчикам следует использовать библиотеки iOS, такие как Google Sign-In для iOS или AppAuth для iOS от OpenID Foundation.

Веб-разработчики могут столкнуться с этой ошибкой, когда приложение для iOS или macOS открывает обычную веб-ссылку во встроенном пользовательском агенте, и пользователь переходит на конечную точку авторизации Google OAuth 2.0 с вашего сайта. Разработчикам следует разрешить открытие обычных ссылок в обработчике ссылок по умолчанию операционной системы, включая обработчики универсальных ссылок или обработчики ссылок браузера по умолчанию. Библиотека SFSafariViewController также является поддерживаемым вариантом.

org_internal

Идентификатор клиента OAuth в запросе является частью проекта, ограничивающего доступ к учетным записям Google в конкретной организации Google Cloud . Для получения дополнительной информации об этом параметре конфигурации см. раздел «Тип пользователя» в справочной статье «Настройка экрана согласия OAuth».

deleted_client

Клиент OAuth, использованный для отправки запроса, был удален. Удаление может произойти вручную или автоматически в случае неиспользуемых клиентов . Удаленные клиенты могут быть восстановлены в течение 30 дней с момента удаления. Подробнее .

invalid_grant

Если вы используете верификатор кода и проверку подлинности , параметр code_callenge недействителен или отсутствует. Убедитесь, что параметр code_challenge установлен правильно.

При обновлении токена доступа может случиться так, что срок его действия истек или он был аннулирован. Повторно аутентифицируйте пользователя и запросите у него согласие на получение новых токенов. Если ошибка повторяется, убедитесь, что ваше приложение настроено правильно и что вы используете корректные токены и параметры в запросе. В противном случае, учетная запись пользователя может быть удалена или отключена.

redirect_uri_mismatch

Передаваемый в запросе авторизации параметр redirect_uri не соответствует разрешенному URI перенаправления для идентификатора клиента OAuth. Проверьте разрешенные URI перенаправления на странице «Клиенты» в консоли Google Cloud.

Переданный redirect_uri может быть недействительным для данного типа клиента.

Параметр redirect_uri может указывать на устаревший и больше не поддерживаемый поток OAuth out-of-band (OOB). Для обновления интеграции обратитесь к руководству по миграции .

invalid_request

В вашем запросе произошла ошибка. Причиной может быть ряд причин:

  • Запрос был оформлен неправильно.
  • В запросе отсутствовали необходимые параметры.
  • В запросе используется метод авторизации, который Google не поддерживает. Убедитесь, что ваша интеграция OAuth использует рекомендуемый метод интеграции.
  • Для URI перенаправления использовалась неподдерживаемая пользовательская схема. Если вы видите сообщение об ошибке «Пользовательская схема URI не поддерживается в приложениях Android или Chrome» , узнайте больше об альтернативных вариантах пользовательских схем URI.

Шаг 4: Обработка ответа сервера OAuth 2.0

Способ получения вашим приложением ответа об авторизации зависит от используемой схемы URI перенаправления . Независимо от схемы, ответ будет содержать либо код авторизации ( code ), либо ошибку ( error ). Например, error=access_denied означает, что пользователь отклонил запрос.

Если пользователь предоставит доступ к вашему приложению, вы можете обменять код авторизации на токен доступа и токен обновления, как описано на следующем шаге.

Шаг 5: Обменяйте код авторизации на токены обновления и доступа.

Для обмена кода авторизации на токен доступа вызовите конечную точку https://oauth2.googleapis.com/token и установите следующие параметры:

Поля
client_id Идентификатор клиента, полученный на странице «Клиенты» в облачной консоли.
client_secret Необязательный

Секретный ключ клиента, полученный на странице «Клиенты» в облачной консоли.

code Код авторизации, полученный в результате первоначального запроса.
code_verifier Созданный вами на шаге 1 верификатор кода.
grant_type В соответствии со спецификацией OAuth 2.0 , значение этого поля должно быть установлено на authorization_code .
redirect_uri Один из URI перенаправления, указанных для вашего проекта на странице «Клиенты» в Cloud Console для заданного client_id .

Хотя использование DPoP необязательно, оно рекомендуется для повышения безопасности. Безопасность DPoP основана на том, что закрытый ключ хранится только на одном устройстве; мы рекомендуем хранить его таким образом, чтобы его нельзя было скопировать за пределы устройства, например, с помощью TPM, защищенных анклавов или других аппаратных хранилищ ключей. Для использования DPoP ваше приложение должно генерировать новый, уникальный JWT-токен подтверждения DPoP для каждого запроса к конечной точке токена и добавлять его в заголовок HTTP-запроса.

Заголовок Необходимый Описание
DPoP Необязательный Доказательство DPoP — это JWT, подтверждающее владение закрытым ключом. Это заголовок, а не параметр. Если он предоставлен, возвращаемые токены привязываются к этому ключу. Для каждого запроса необходимо генерировать новое уникальное доказательство, которое должно включать утверждения htm (метод HTTP) и htu (URI HTTP), соответствующие запросу.

Следующий фрагмент кода демонстрирует пример запроса:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
redirect_uri=http://127.0.0.1:9004&
grant_type=authorization_code

Создайте доказательство DPoP.

Следующие шаги показывают, как создать доказательство DPoP с помощью OpenSSL из командной строки:

  1. Сгенерируйте пару ключей EC P-256:
    openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem
    openssl ec -in dpop_private.pem -pubout -out dpop_public.pem
  2. Создайте заголовок DPoP:

    Заголовок должен содержать утверждения typ , alg и jwk (открытый ключ). Значения x и y — это закодированные в Base64Url координаты вашего открытого ключа EC. Закодируйте этот JSON в Base64Url:

    {
      "typ":"dpop+jwt",
      "alg":"ES256",
      "jwk": {
        "kty":"EC",
        "x":"YOUR_PUBLIC_KEY_X",
        "y":"YOUR_PUBLIC_KEY_Y",
        "crv":"P-256"
      }
    }
  3. Создайте полезную нагрузку DPoP:

    Полезная нагрузка должна включать jti (уникальный идентификатор запроса), htm (метод HTTP, например, POST ), htu (URI HTTP, например, https://oauth2.googleapis.com/token ) и iat (дата выдачи). Если вы получили nonce от сервера в заголовке DPoP-Nonce в ответе на предыдущий запрос, вы должны включить это значение nonce в утверждение nonce . Утверждение nonce является необязательным для обмена кодами авторизации и используется только в том случае, если заголовок DPoP-Nonce был получен ранее. Закодируйте этот JSON в Base64Url:

    {
      "jti":"JTI_VALUE",
      "htm":"POST",
      "htu":"https://oauth2.googleapis.com/token",
      "iat":YOUR_JWT_ISSUED_TIME,
      "nonce":"SERVER_PROVIDED_NONCE"
    }

    Значение jti зависит от типа обмена:

    • Для обмена кодами авторизации jti должен представлять собой закодированный в Base64Url хеш SHA256 кода авторизации: "jti":" BASE64URL(SHA256(AUTHORIZATION_CODE)) " .
    • Для обмена токенов обновления jti должен быть уникальным идентификатором для каждого запроса: "jti":" YOUR_UNIQUE_PER_REQUEST_IDENTIFIER " .
  4. Подпишите подтверждение:

    Объедините закодированный заголовок и полезную нагрузку точкой ( . ), затем подпишите результат своим закрытым ключом, используя ES256. Обратите внимание, что JWS требует, чтобы подпись была в необработанном формате R | S (64 байта для P-256). При использовании OpenSSL напрямую необходимо преобразовать стандартную подпись в формате ASN.1 DER в этот необработанный формат.

Успешный обмен подтверждается ответом 200 OK содержащим токены. Если во время обмена используется действительное подтверждение DPoP, токен обновления, возвращаемый Google, будет привязан к вашему ключу через DPoP, но токены доступа не будут привязаны к DPoP. Токены доступа сохранят token_type Bearer , а не DPoP . Кроме того, Google возвращает HTTP-заголовок DPoP-Nonce в ответе. Ваш клиент должен кэшировать этот nonce и включать его в утверждение nonce подтверждения DPoP в последующих запросах (например, при обмене токена обновления на новый токен доступа или при вызове API, защищенных DPoP). Используя этот заранее выданный nonce, вы можете избежать дополнительной ошибки при повторном обращении ( use_dpop_nonce ) в следующем запросе.

Для запросов на обмен токенов, выполняемых с использованием токенов обновления, привязанных к DPoP, необходимо приложить подтверждение DPoP.

Неудачный обмен происходит, если заголовок DPoP отсутствует, когда ожидалось, является недействительным, или если в подтверждении используется другой ключ, отличный от того, который привязан к токену. В этих случаях сервер возвращает ошибку 400 Bad Request . Если в подтверждении DPoP содержатся несовпадающие утверждения htm или htu , истек срок действия iat , повторно используется jti или недействительная подпись, Google возвращает код ошибки invalid_dpop_proof . Если требуется nonce для DPoP, например, при обмене токенов обновления, и в подтверждении DPoP отсутствует утверждение nonce , или значение nonce неприемлемо для сервера (например, оно истекло, уже использовалось или неверно), Google возвращает код ошибки use_dpop_nonce вместе с HTTP-заголовком DPoP-Nonce содержащим новый nonce, который можно использовать в последующем запросе. Другие сбои могут возвращать invalid_grant .

В ответ на этот запрос Google возвращает JSON-объект, содержащий кратковременный токен доступа и токен обновления.

Ответ содержит следующие поля:

Поля
access_token Токен, который ваше приложение отправляет для авторизации запроса к API Google.
expires_in Оставшийся срок действия токена доступа в секундах.
id_token Примечание: это свойство возвращается только в том случае, если ваш запрос включал область идентификации, например, openid , profile или email . Значение представляет собой JSON Web Token (JWT), содержащий цифровую подпись, указывающую на личность пользователя.
refresh_token Токен, который можно использовать для получения нового токена доступа. Токены обновления действительны до тех пор, пока пользователь не отзовет доступ или пока срок действия токена обновления не истечет. Если использовался DPoP, токен обновления привязан к закрытому ключу, использованному для подписи подтверждения DPoP. Обратите внимание, что токены обновления всегда возвращаются для установленных приложений.
refresh_token_expires_in Оставшийся срок действия токена обновления в секундах. Это значение устанавливается только в том случае, если пользователь предоставляет доступ по времени .
scope Области доступа, предоставляемые access_token выражены в виде списка строк, разделенных пробелами и чувствительных к регистру.
token_type Тип возвращаемого токена. Это значение всегда Bearer , даже при использовании DPoP.

Следующий фрагмент кода демонстрирует пример заголовков и тела успешного ответа при использовании DPoP:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Шаг 6: Проверьте, какие права доступа были предоставлены пользователям.

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

Однако есть исключения. Приложения Google Workspace Enterprise с делегированием полномочий на уровне домена или приложения, помеченные как «Доверенные» , обходят экран подтверждения согласия на предоставление детальных разрешений. Для таких приложений пользователи не увидят экран подтверждения согласия на предоставление детальных разрешений. Вместо этого ваше приложение получит либо все запрошенные области действия, либо ни одной.

Более подробную информацию см. в разделе «Как управлять детализированными правами доступа» .

Чтобы проверить, предоставил ли пользователь вашему приложению доступ к определенной области действия, изучите поле scope в ответе, полученном от access_token. Области действия, предоставленные access_token, представлены в виде списка строк, разделенных пробелами и чувствительных к регистру.

Например, следующий пример ответа в виде токена доступа указывает на то, что пользователь предоставил вашему приложению доступ только для чтения к действиям в Google Диска и событиям Календаря:

  {
    "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
    "expires_in": 3920,
    "token_type": "Bearer",
    "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
    "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
  }

Вызов API Google

После получения токена доступа ваше приложение может использовать его для вызова API Google от имени учетной записи пользователя, если предоставлены необходимые для API права доступа. Для этого включите токен доступа в запрос к API, указав либо параметр запроса access_token , либо значение заголовка HTTP Authorization Bearer . По возможности предпочтительнее использовать заголовок HTTP, поскольку строки запроса обычно видны в логах сервера. В большинстве случаев вы можете использовать клиентскую библиотеку для настройки вызовов к API Google (например, при вызове API файлов Google Drive ).

Вы можете протестировать все API Google и ознакомиться с их областями действия на платформе OAuth 2.0 Playground .

Примеры HTTP GET-запросов

Вызов конечной точки drive.files (API файлового сервиса Drive) с использованием HTTP-заголовка Authorization: Bearer может выглядеть следующим образом. Обратите внимание, что вам необходимо указать собственный токен доступа:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Вот вызов того же API для аутентифицированного пользователя с использованием параметра строки запроса access_token :

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

примеры curl

Вы можете протестировать эти команды с помощью приложения командной строки curl . Вот пример, использующий опцию заголовка HTTP (предпочтительный вариант):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Или, в качестве альтернативы, можно использовать параметр строки запроса:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Обновить токен доступа

Токены доступа периодически истекают и становятся недействительными учетными данными для соответствующего запроса API. Вы можете обновить токен доступа без запроса разрешения у пользователя (в том числе, когда пользователь отсутствует), если вы запросили автономный доступ к областям действия, связанным с токеном.

Для обновления токена доступа ваше приложение отправляет HTTPS POST запрос на сервер авторизации Google ( https://oauth2.googleapis.com/token ), который включает в тело запроса следующие параметры:

Имя Ценить
client_id Идентификатор клиента, полученный из консоли API .
client_secret Необязательный

Секретный ключ клиента, полученный из консоли API . ( client_secret не применяется к запросам от клиентов, зарегистрированных как приложения Android, iOS или Chrome.)

grant_type В соответствии со спецификацией OAuth 2.0 , значение этого поля должно быть установлено на refresh_token .
refresh_token Токен обновления, полученный в результате обмена кодами авторизации.

Хотя использование DPoP необязательно, оно рекомендуется для повышения безопасности. Для использования DPoP с токеном обновления ваше приложение должно генерировать новый, уникальный JWT-доказательство DPoP для каждого запроса к конечной точке токена. Это доказательство должно быть подписано тем же закрытым ключом, который использовался при первоначальном обмене кодами авторизации. Ваше приложение добавляет доказательство в заголовок HTTP-запроса.

Заголовок Необходимый Описание
DPoP Необязательный Доказательство DPoP — это JWT, подтверждающее владение закрытым ключом. Это заголовок, а не параметр. Если он предоставлен, возвращаемые токены привязываются к этому ключу. Для каждого запроса необходимо генерировать новое уникальное доказательство, которое должно включать утверждения htm (метод HTTP) и htu (URI HTTP), соответствующие запросу.

Следующий фрагмент кода демонстрирует пример запроса:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
DPoP: DPOP_PROOF_JWT

client_id=your_client_id&
refresh_token=refresh_token&
grant_type=refresh_token

Для использования DPoP с токеном обновления необходимо сгенерировать новый уникальный JWT-токен подтверждения DPoP для запроса. Пошаговые инструкции по генерации пары ключей и созданию JWT см. в разделе «Создание подтверждения DPoP» .

Успешный обмен подтверждается ответом 200 OK содержащим новый токен доступа. При использовании DPoP token_type Bearer . Успешный ответ подтверждает принятие подтверждения DPoP для токена обновления. Google также может вернуть новый HTTP-заголовок DPoP-Nonce в ответе; если он возвращен, ваш клиент должен кэшировать этот nonce и включать его в утверждение nonce подтверждения DPoP в последующих запросах.

Неудачный обмен происходит, если заголовок DPoP отсутствует, недействителен или использует неправильный ключ. Подробную информацию о конкретных кодах ошибок DPoP и обработке одноразовых чисел см. в разделе «Неудачный обмен» .

Следующий фрагмент кода демонстрирует пример заголовков и тела успешного ответа при использовании DPoP:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
  "token_type": "Bearer"
}

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

аннулирование токена

В некоторых случаях пользователь может захотеть отозвать предоставленный приложению доступ. Отозвать доступ можно, перейдя в «Настройки учетной записи» . Дополнительную информацию см. в разделе «Удаление доступа к сайту или приложению» документа поддержки «Сторонние сайты и приложения, имеющие доступ к вашей учетной записи» .

Приложение также может программно отозвать предоставленный ему доступ. Программный отзыв важен в случаях, когда пользователь отписывается от рассылки, удаляет приложение или существенно изменяются ресурсы API, необходимые приложению. Другими словами, часть процесса удаления может включать в себя запрос к API для обеспечения удаления ранее предоставленных приложению разрешений.

Для программного отзыва токена ваше приложение отправляет запрос на https://oauth2.googleapis.com/revoke и передает токен в качестве параметра:

curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
        https://oauth2.googleapis.com/revoke?token={token}

Токен может быть токеном доступа или токеном обновления. Если токен является токеном доступа и имеет соответствующий токен обновления, токен обновления также будет аннулирован.

Если запрос на отзыв успешно обработан, то HTTP-статус ответа равен 200 В случае ошибки возвращается HTTP-статус 400 вместе с кодом ошибки.

методы перенаправления приложения

Пользовательская схема URI

Пользовательские URI-схемы — это разновидность глубоких ссылок, использующая заданную пользователем схему для открытия вашего приложения.

Альтернатива использованию пользовательских схем URI в приложениях Chrome.

Используйте API Chrome Identity , который передает ответ OAuth 2.0 непосредственно в ваше приложение, устраняя необходимость в URI перенаправления.

IP-адрес замыкающей петли (macOS, Linux, Windows)

To receive the authorization code using this URL, your application must be listening on the local web server. That is possible on many, but not all, platforms. However, if your platform supports it, this is the recommended mechanism for obtaining the authorization code.

When your app receives the authorization response, for best usability it should respond by displaying an HTML page that instructs the user to close the browser and return to your app.

Рекомендуемое использование macOS, Linux, and Windows desktop (but not Universal Windows Platform) apps
Form values Set the application type to Desktop app .

Manual copy/paste (Deprecated)

Protect your apps

Verify app ownership for Chrome

You can verify ownership of your application to reduce the risk of app impersonation.

To complete the verification process, you would use your Chrome Web Store Developer account. The following requirements must be met for a successful verification:

  • You must have a registered item in the Chrome Web Store Developer Dashboard with the same item ID as the Chrome Extension OAuth client you are completing the verification for.
  • You must be a publisher for the Chrome Web Store item. Learn more about access management in the Chrome Web Store Developer Dashboard.

In the Verify App Ownership section of the Chrome Extension client, click the Verify Ownership button to complete the verification process.

Note: Wait a few minutes before completing the verification process after granting access to your account.

If the verification is successful, a notification will be displayed to confirm the success of the verification process. Otherwise, an error prompt will be shown.

To fix a failed verification, try the following:

  • Make sure there is a registered item in the Chrome Web Store Developer Dashboard with the same item ID as the Chrome Extension OAuth client you are completing the verification for.
  • Make sure you are a publisher for the app, that is, you must either be the individual publisher of the app or a member of the group publisher of the app. Learn more about access management in the Chrome Web Store Developer Dashboard.
  • If you just updated your group publisher list, verify that the group publisher membership list is synced in the Chrome Web Store Developer Dashboard. Learn more about syncing your publisher membership list.

App Check (iOS only)

The App Check feature helps safeguard your iOS applications from unauthorized usage by using Apple's App Attest service to verify that requests made to Google OAuth 2.0 endpoints originate from your authentic applications. This helps to reduce the risk of app impersonation.

Enable App Check for your iOS Client

The following requirements must be met to successfully enable App Check for your iOS client:
  • You must specify a team ID for your iOS client.
  • You must not use a wildcard in your bundle ID since it can resolve to more than one app. This means that the bundle ID must not include the asterisk (*) symbol.
To enable App Check, turn on the Protect your OAuth client from abuse with Firebase App Check toggle button in the edit view of your iOS client.

After enabling App Check, you will start seeing metrics related to OAuth requests from your client in the edit view of the OAuth client. Requests from unverified sources won't be blocked until you enforce App Check . The information in the metrics monitoring page can help you determine when to start enforcement.

You might see errors related to the App Check feature when enabling App Check for your iOS app. To fix these errors, try the following:

  • Verify that the bundle ID and team ID you specified are valid.
  • Verify that you are not using a wildcard for the bundle ID.

Enforce App Check for your iOS Client

Enabling App Check for your app does not automatically block unrecognized requests. To enforce this protection, go to the edit view of your iOS client. There, you will see App Check metrics to the right of the page under the Google Identity for iOS section. The metrics include the following information:
  • Number of verified requests - requests that have a valid App Check token. After you enable App Check enforcement, only requests in this category will succeed.
  • Number of unverified requests: likely outdated client requests - requests missing an App Check token; these request may be from an older version of your app that doesn't include an App Check implementation.
  • Number of unverified requests: unknown origin requests - requests missing an App Check token that don't look like they are coming from your app.
  • Number of unverified requests: invalid requests - requests with an invalid App Check token, which may be from an inauthentic client attempting to impersonate your app, or from emulated environments.
Review these metrics to understand how enforcing App Check will affect your users.

To enforce App Check, click the ENFORCE button and confirm your choice. Once enforcement is active, all unverified requests from your client will be rejected.

Note : after you enable enforcement, it can take up to 15 minutes for the changes to take effect.

Unenforce App Check for your iOS Client

Unenforcing App Check for your app will stop enforcement and will allow all requests from your client to Google OAuth 2.0 endpoints, including unverified requests.

To unenforce App Check for your iOS client, navigate to the edit view of the iOS client and click the UNENFORCE button and confirm your choice.

Note : after unenforcing App Check, it can take up to 15 minutes for the changes to take effect.

Disable App Check for your iOS Client

Disabling App Check for your app will stop all App Check monitoring and enforcement . Consider unenforcing App Check instead so you can continue monitoring metrics for your client.

To disable App Check for your iOS client, navigate to the edit view of the iOS client and turn off the Protect your OAuth client from abuse with Firebase App Check toggle button.

Note : after disabling App Check, it can take up to 15 minutes for the changes to take effect.

Time-based access

Time-based access allows a user to grant your app access to their data for a limited duration to complete an action. Time-based access is available in select Google products during the consent flow, giving users the option to grant access for a limited period of time. An example is the Data Portability API which enables a one-time transfer of data.

When a user grants your application time-based access, the refresh token will expire after the specified duration. Note that refresh tokens may be invalidated earlier under specific circumstances; see these cases for details. The refresh_token_expires_in field returned in the authorization code exchange response represents the time remaining until the refresh token expires in such cases.

Дополнительная литература

The IETF Best Current Practice OAuth 2.0 for Native Apps establishes many of the best practices documented here.

Implement Cross-Account Protection

An additional step you should take to protect your users' accounts is implementing Cross-Account Protection by utilizing Google's Cross-Account Protection Service. This service lets you subscribe to security event notifications which provide information to your application about major changes to the user account. You can then use the information to take action depending on how you decide to respond to events.

Some examples of the event types sent to your app by Google's Cross-Account Protection Service are:

  • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
  • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
  • https://schemas.openid.net/secevent/risc/event-type/account-disabled

See the Protect user accounts with Cross-Account Protection page for more information on how to implement Cross Account Protection and for the full list of available events.