OAuth 2.0 для телевизоров и приложений с ограниченным вводом данных

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

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

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

Альтернативы

Если вы пишете приложение для такой платформы, как Android, iOS, macOS, Linux или Windows (включая универсальную платформу Windows), которое имеет доступ к браузеру и полные возможности ввода, используйте поток OAuth 2.0 для мобильных и настольных приложений . (Вам следует использовать этот процесс, даже если ваше приложение представляет собой инструмент командной строки без графического интерфейса.)

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

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

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

Любое приложение, которое вызывает API Google, должно включить эти API в API Console.

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

  1. Open the API Library в Google API Console.
  2. If prompted, select a project, or create a new one.
  3. API Library перечисляет все доступные API, сгруппированные по семействам продуктов и популярности. Если API, который вы хотите включить, не отображается в списке, воспользуйтесь поиском, чтобы найти его, или нажмите «Просмотреть все» в семействе продуктов, к которому он принадлежит.
  4. Выберите API, который вы хотите включить, затем нажмите кнопку «Включить» .
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

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

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

  1. Go to the Credentials page.
  2. Нажмите Создать учетные данные > Идентификатор клиента OAuth .
  3. Выберите тип приложения «Телевизоры и устройства ограниченного ввода» .
  4. Назовите свой клиент OAuth 2.0 и нажмите «Создать» .

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

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

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

См. список разрешенных областей для установленных приложений или устройств.

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

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

  1. Ваше приложение отправляет запрос на сервер авторизации Google, который определяет области, к которым ваше приложение будет запрашивать разрешение на доступ.
  2. Сервер отвечает несколькими фрагментами информации, используемыми на последующих этапах, например кодом устройства и кодом пользователя.
  3. Вы отображаете информацию, которую пользователь может ввести на отдельном устройстве для авторизации вашего приложения.
  4. Ваше приложение начинает опрашивать сервер авторизации Google, чтобы определить, авторизовал ли пользователь ваше приложение.
  5. Пользователь переключается на устройство с более широкими возможностями ввода, запускает веб-браузер, переходит по URL-адресу, отображаемому на шаге 3, и вводит код, который также отображается на шаге 3. Затем пользователь может предоставить (или запретить) доступ к вашему приложению.
  6. Следующий ответ на ваш запрос на опрос содержит токены, необходимые вашему приложению для авторизации запросов от имени пользователя. (Если пользователь отказал в доступе к вашему приложению, ответ не содержит токенов.)

Изображение ниже иллюстрирует этот процесс:

Пользователь входит в систему на отдельном устройстве, на котором есть браузер.

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

Шаг 1. Запросите коды устройства и пользователя.

На этом этапе ваше устройство отправляет HTTP-запрос POST на сервер авторизации Google по адресу https://oauth2.googleapis.com/device/code , который идентифицирует ваше приложение, а также области доступа, к которым ваше приложение хочет получить доступ на странице пользователя. от имени. Вам следует получить этот URL-адрес из документа Discovery, используя значение метаданных device_authorization_endpoint . Включите следующие параметры HTTP-запроса:

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

Идентификатор клиента для вашего приложения. Вы можете найти это значение в API ConsoleCredentials page.

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

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

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

Примеры

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

POST /device/code HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=client_id&scope=email%20profile

В этом примере показана команда curl для отправки того же запроса:

curl -d "client_id=client_id&scope=email%20profile" \
     https://oauth2.googleapis.com/device/code

Шаг 2. Обработка ответа сервера авторизации

Сервер авторизации вернет один из следующих ответов:

Успешный ответ

Если запрос действителен, вашим ответом будет объект JSON, содержащий следующие свойства:

Характеристики
device_code Значение, которое Google присваивает уникальным образом для идентификации устройства, на котором запущено приложение, запрашивающее авторизацию. Пользователь будет авторизовать это устройство с другого устройства с более широкими возможностями ввода. Например, пользователь может использовать ноутбук или мобильный телефон для авторизации приложения, работающего на телевизоре. В этом случае device_code идентифицирует телевизор.

Этот код позволяет устройству, на котором запущено приложение, безопасно определить, предоставил ли пользователь доступ или запретил его.

expires_in Продолжительность времени в секундах, в течение которого действительны device_code и user_code . Если за это время пользователь не завершит процесс авторизации и ваше устройство также не проведет опрос для получения информации о решении пользователя, возможно, вам придется перезапустить этот процесс с шага 1.
interval Промежуток времени в секундах, в течение которого ваше устройство должно ожидать между запросами опроса. Например, если значение равно 5 , ваше устройство должно отправлять запрос на опрос на сервер авторизации Google каждые пять секунд. См. шаг 3 для получения более подробной информации.
user_code Значение с учетом регистра, которое идентифицирует Google области, к которым приложение запрашивает доступ. Ваш пользовательский интерфейс предложит пользователю ввести это значение на отдельном устройстве с более широкими возможностями ввода. Затем Google использует это значение для отображения правильного набора областей, предлагая пользователю предоставить доступ к вашему приложению.
verification_url URL-адрес, по которому пользователь должен перейти на отдельном устройстве, чтобы ввести user_code и предоставить или запретить доступ к вашему приложению. Ваш пользовательский интерфейс также отобразит это значение.

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

{
  "device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
  "user_code": "GQVQ-JKEC",
  "verification_url": "https://www.google.com/device",
  "expires_in": 1800,
  "interval": 5
}

Квота превышена, ответ

Если запросы кода вашего устройства превысили квоту, связанную с вашим идентификатором клиента, вы получите ответ 403, содержащий следующую ошибку:

{
  "error_code": "rate_limit_exceeded"
}

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

Шаг 3. Отобразите код пользователя

Отобразите пользователю verification_url и user_code полученные на шаге 2. Оба значения могут содержать любой печатный символ из набора символов US-ASCII. Содержимое, которое вы показываете пользователю, должно содержать указание пользователю перейти к verification_url на отдельном устройстве и ввести user_code .

При разработке пользовательского интерфейса (UI) учитывайте следующие правила:

  • user_code
    • user_code должен отображаться в поле, которое может обрабатывать 15 символов размера «W». Другими словами, если вы можете правильно отобразить код WWWWWWWWWWWWWWW , ваш пользовательский интерфейс действителен, и мы рекомендуем использовать это строковое значение при тестировании способа отображения user_code в вашем пользовательском интерфейсе.
    • user_code чувствителен к регистру и не должен каким-либо образом изменяться, например, изменять регистр или вставлять другие символы форматирования.
  • verification_url
    • Пространство, в котором вы отображаете verification_url должно быть достаточно широким, чтобы обрабатывать строку URL-адреса длиной 40 символов.
    • Не следует каким-либо образом изменять verification_url , кроме как при необходимости удалить схему для отображения. Если вы планируете удалить схему (например https:// ) из URL-адреса по соображениям отображения, убедитесь, что ваше приложение может обрабатывать варианты http и https .

Шаг 4. Опросите сервер авторизации Google.

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

Запрашивающее устройство должно продолжать отправлять запросы опроса до тех пор, пока оно не получит ответ, указывающий, что пользователь ответил на запрос доступа, или пока не истечет срок действия device_code и user_code полученных на шаге 2 . interval , возвращаемый на шаге 2, определяет количество времени в секундах ожидания между запросами.

URL-адрес конечной точки опроса: https://oauth2.googleapis.com/token . Запрос на опрос содержит следующие параметры:

Параметры
client_id Идентификатор клиента для вашего приложения. Вы можете найти это значение в API ConsoleCredentials page.
client_secret Секрет клиента для предоставленного client_id . Вы можете найти это значение в API ConsoleCredentials page.
device_code device_code , возвращенный сервером авторизации на шаге 2 .
grant_type Установите для этого значения значение urn:ietf:params:oauth:grant-type:device_code .

Примеры

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

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

client_id=client_id&
client_secret=client_secret&
device_code=device_code&
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code

В этом примере показана команда curl для отправки того же запроса:

curl -d "client_id=client_id&client_secret=client_secret& \
         device_code=device_code& \
         grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code" \
         -H "Content-Type: application/x-www-form-urlencoded" \
         https://oauth2.googleapis.com/token

Шаг 5. Пользователь отвечает на запрос доступа.

На следующем изображении показана страница, похожая на ту, которую видят пользователи, когда переходят по URL verification_url , который вы отображали на шаге 3 :

Подключите устройство, введя код

После ввода user_code и, если он еще не вошел в систему, входа в Google, пользователь видит экран согласия, подобный показанному ниже:

Пример экрана согласия для клиента устройства

Шаг 6. Обработка ответов на запросы опроса

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

Доступ предоставлен

Если пользователь предоставил доступ к устройству (нажав Allow на экране согласия), то ответ содержит токен доступа и токен обновления. Токены позволяют вашему устройству получать доступ к API Google от имени пользователя. (Свойство scope в ответе определяет, к каким API-интерфейсам может получить доступ устройство.)

В этом случае ответ API содержит следующие поля:

Поля
access_token Токен, который ваше приложение отправляет для авторизации запроса Google API.
expires_in Оставшийся срок действия токена доступа в секундах.
refresh_token Токен, который можно использовать для получения нового токена доступа. Токены обновления действительны до тех пор, пока пользователь не отзовет доступ. Обратите внимание, что токены обновления всегда возвращаются для устройств.
scope Области доступа, предоставляемые access_token выражаются в виде списка строк, разделенных пробелами и чувствительных к регистру.
token_type Тип возвращенного токена. В настоящее время значение этого поля всегда установлено на Bearer .

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

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "token_type": "Bearer",
  "refresh_token": "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

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

Доступ запрещен

Если пользователь отказывается предоставить доступ к устройству, то ответ сервера имеет код состояния ответа HTTP 403 ( Forbidden ). В ответе содержится следующая ошибка:

{
  "error": "access_denied",
  "error_description": "Forbidden"
}

Ожидается авторизация

Если пользователь еще не завершил поток авторизации, сервер возвращает код состояния ответа HTTP 428 ( Precondition Required ). В ответе содержится следующая ошибка:

{
  "error": "authorization_pending",
  "error_description": "Precondition Required"
}

Опрос слишком частый

Если устройство слишком часто отправляет запросы на опрос, сервер возвращает код состояния ответа HTTP 403 ( Forbidden ). В ответе содержится следующая ошибка:

{
  "error": "slow_down",
  "error_description": "Forbidden"
}

Другие ошибки

Сервер авторизации также возвращает ошибки, если в запросе опроса отсутствуют какие-либо обязательные параметры или указано неверное значение параметра. Эти запросы обычно имеют код состояния ответа HTTP 400 ( Bad Request ) или 401 ( Unauthorized ). Эти ошибки включают в себя:

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

Клиент OAuth не найден. Например, эта ошибка возникает, если значение параметра client_id недопустимо.

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

invalid_grant 400 Значение параметра code недопустимо, уже заявлено или не может быть проанализировано.
unsupported_grant_type 400 Недопустимое значение grant_type .
org_internal 403 Идентификатор клиента OAuth в запросе является частью проекта, ограничивающего доступ к аккаунтам Google в конкретной организации Google Cloud . Подтвердите конфигурацию типа пользователя для вашего приложения OAuth.

Вызов API Google

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

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

Примеры HTTP GET

Вызов конечной точки drive.files (API Drive Files) с использованием 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 Console.
client_secret Секрет клиента, полученный от API Console.
grant_type Как определено в спецификации OAuth 2.0 , для этого поля должно быть установлено refresh_token .
refresh_token Токен обновления, возвращенный в результате обмена кодами авторизации.

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

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

client_id=your_client_id&
client_secret=your_client_secret&
refresh_token=refresh_token&
grant_type=refresh_token

Пока пользователь не отозвал доступ, предоставленный приложению, сервер токенов возвращает объект JSON, содержащий новый токен доступа. В следующем фрагменте показан пример ответа:

{
  "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 возвращается вместе с кодом ошибки.

Разрешенные области

Поток OAuth 2.0 для устройств поддерживается только в следующих областях:

OpenID Connect , вход в Google

  • email
  • openid
  • profile

API Диска

  • https://www.googleapis.com/auth/drive.appdata
  • https://www.googleapis.com/auth/drive.file

API YouTube

  • https://www.googleapis.com/auth/youtube
  • https://www.googleapis.com/auth/youtube.readonly

Реализация защиты между аккаунтами

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

Вот некоторые примеры типов событий, отправляемых в ваше приложение службой защиты нескольких аккаунтов Google:

  • 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

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