OpenID Connect

Конечная точка OpenID Connect от Google имеет сертификат OpenID.

API Google OAuth 2.0 можно использовать как для аутентификации, так и для авторизации. В этом документе описывается наша реализация аутентификации OAuth 2.0, которая соответствует спецификации OpenID Connect и сертифицирована OpenID . Документация, приведенная в разделе «Использование OAuth 2.0 для доступа к API Google», также применима к этому сервису. Если вы хотите изучить этот протокол в интерактивном режиме, мы рекомендуем Google OAuth 2.0 Playground . Чтобы получить помощь на Stack Overflow , пометьте свои вопросы тегом «google-oauth».

Настройка OAuth 2.0

Прежде чем ваше приложение сможет использовать систему аутентификации Google OAuth 2.0 для входа пользователей, необходимо настроить проект в... Google Cloud Console Чтобы получить учетные данные OAuth 2.0, установить URI перенаправления и (при желании) настроить информацию о брендинге, которую пользователи видят на экране согласия пользователя. Вы также можете использовать Cloud Console Для создания учетной записи службы, включения выставления счетов, настройки фильтрации и выполнения других задач. Более подробную информацию см. в разделе Google Cloud Console Помощь .

Получите учетные данные OAuth 2.0.

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

Чтобы просмотреть идентификатор клиента и секретный ключ клиента для заданных учетных данных OAuth 2.0, щелкните следующий текст: Выберите учетные данные . В открывшемся окне выберите свой проект и нужные учетные данные, затем нажмите «Просмотреть» .

Или же, просмотрите свой идентификатор клиента и секретный ключ клиента вClients page вCloud Console:

  1. Go to the Clients page.
  2. Щелкните по имени вашего клиента или по значку редактирования ( ). Ваш идентификатор клиента и секретный ключ находятся в верхней части страницы.

Задайте URI перенаправления

URI перенаправления, который вы задали в Cloud Console определяет, куда Google отправляет ответы на ваши запросы аутентификации .

Чтобы создать, просмотреть или отредактировать URI перенаправления для заданных учетных данных OAuth 2.0, выполните следующие действия:

  1. Go to the Clients page.
  2. Нажмите на клиента.
  3. Просмотреть или отредактировать URI перенаправления.

Если на странице «Клиенты» нет указанного клиента, значит, у вашего проекта отсутствуют учетные данные OAuth. Чтобы создать их, нажмите «Создать клиента» .

Настройте экран согласия пользователя.

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

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

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

  1. Откройте Branding page в Google Cloud Console.
  2. If prompted, select a project, or create a new one.
  3. Заполните форму и нажмите «Сохранить» .

Приведенное ниже диалоговое окно согласия показывает, что увидит пользователь, если в запросе присутствует комбинация областей действия OAuth 2.0 и Google Drive. (Это стандартное диалоговое окно было сгенерировано с помощью Google OAuth 2.0 Playground , поэтому оно не содержит информации о брендинге, которая устанавливается в запросе.) Cloud Console.)

Пример страницы согласия
Рисунок 1. Скриншот страницы согласия.

Доступ к сервису

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

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

Аутентификация пользователя

Аутентификация пользователя включает в себя получение идентификационного токена и его проверку. Идентификационные токены — это стандартизированная функция OpenID Connect , предназначенная для использования при обмене подтверждениями личности в Интернете.

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

В этом документе описывается, как реализовать серверный процесс аутентификации пользователя. Неявный процесс значительно сложнее из-за рисков безопасности, связанных с обработкой и использованием токенов на стороне клиента. Если вам необходимо реализовать неявный процесс, мы настоятельно рекомендуем использовать Google Identity Services .

Поток сервера

Убедитесь, что вы настроили свое приложение в Cloud Console Чтобы разрешить использование этих протоколов и аутентифицировать ваших пользователей. Когда пользователь пытается войти в систему с помощью Google, вам необходимо:

  1. Создайте токен состояния защиты от подделки
  2. Отправьте запрос на аутентификацию в Google.
  3. Подтвердите токен состояния защиты от подделки.
  4. Обменяйте code на токен доступа и идентификационный токен.
  5. Получить информацию о пользователе из токена идентификации.
  6. Аутентификация пользователя

1. Создайте токен состояния защиты от подделки.

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

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

Приведенный ниже код демонстрирует генерацию уникальных токенов сессии.

PHP

Для использования этого примера необходимо загрузить клиентскую библиотеку Google API для PHP .

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = bin2hex(random_bytes(128/8));
$app['session']->set('state', $state);
// Set the client ID, token state, and application name in the HTML while
// serving it.
return $app['twig']->render('index.html', array(
    'CLIENT_ID' => CLIENT_ID,
    'STATE' => $state,
    'APPLICATION_NAME' => APPLICATION_NAME
));

Java

Для использования этого примера необходимо загрузить клиентскую библиотеку Google API для Java .

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
request.session().attribute("state", state);
// Read index.html into memory, and set the client ID,
// token state, and application name in the HTML before serving it.
return new Scanner(new File("index.html"), "UTF-8")
    .useDelimiter("\\A").next()
    .replaceAll("[{]{2}\\s*CLIENT_ID\\s*[}]{2}", CLIENT_ID)
    .replaceAll("[{]{2}\\s*STATE\\s*[}]{2}", state)
    .replaceAll("[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}",
    APPLICATION_NAME);

Python

Для использования этого примера необходимо загрузить клиентскую библиотеку Google API для Python .

# Create a state token to prevent request forgery.
# Store it in the session for later validation.
state = hashlib.sha256(os.urandom(1024)).hexdigest()
session['state'] = state
# Set the client ID, token state, and application name in the HTML while
# serving it.
response = make_response(
    render_template('index.html',
                    CLIENT_ID=CLIENT_ID,
                    STATE=state,
                    APPLICATION_NAME=APPLICATION_NAME))

2. Отправьте запрос на аутентификацию в Google.

Следующий шаг — формирование HTTPS GET запроса с соответствующими параметрами URI. Обратите внимание на использование HTTPS вместо HTTP на всех этапах этого процесса; HTTP-соединения будут отклонены. Вам следует получить базовый URI из документа Discovery , используя значение метаданных authorization_endpoint . В дальнейшем обсуждении предполагается, что базовый URI — https://accounts.google.com/o/oauth2/v2/auth .

Для простого запроса укажите следующие параметры:

  • client_id , который вы получаете из Cloud ConsoleClients page.
  • response_type , который в запросе с использованием базового кода авторизации должен быть code . (Подробнее см. response_type .)
  • scope , который в базовом запросе должен быть openid email . (Подробнее см. scope .)
  • redirect_uri должен указывать HTTP-адрес конечной точки на вашем сервере, которая будет получать ответ от Google. Значение должно точно совпадать с одним из авторизованных URI перенаправления для клиента OAuth 2.0, который вы настроили. Cloud ConsoleCredentials pageЕсли это значение не соответствует авторизованному URI, запрос завершится ошибкой redirect_uri_mismatch .
  • state должно включать значение уникального токена сессии для защиты от подделки, а также любую другую информацию, необходимую для восстановления контекста при повторном обращении пользователя к вашему приложению, например, начальный URL-адрес. (Подробнее см. в state ».)
  • nonce — это случайное значение, генерируемое вашим приложением, которое включает защиту от повторного воспроизведения, если оно присутствует.
  • login_hint может содержать адрес электронной почты пользователя или sub , эквивалентную идентификатору пользователя в Google. Если вы не укажете login_hint , а пользователь авторизован, на экране согласия будет отображаться запрос на разрешение предоставить адрес электронной почты пользователя вашему приложению. (Подробнее см. в разделе login_hint .)
  • Используйте параметр hd для оптимизации процесса OpenID Connect для пользователей определенного домена, связанного с организацией Google Workspace или Cloud (подробнее см. hd ).

Вот пример полного URI аутентификации OpenID Connect, с переносами строк и пробелами для удобства чтения:

https://accounts.google.com/o/oauth2/v2/auth?
 response_type=code&
 client_id=424911365001.apps.googleusercontent.com&
 scope=openid%20email&
 redirect_uri=https%3A//developers.google.com/oauthplayground&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2-login-demo.example.com%2FmyHome&
 login_hint=jsmith@example.com&
 nonce=0394852-3190485-2490358&
 hd=example.com

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

3. Подтвердите токен состояния защиты от подделки.

Ответ отправляется на указанный вами в запросе redirect_uri . Все ответы возвращаются в строке запроса:

https://developers.google.com/oauthplayground?state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foa2cb.example.com%2FmyHome&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&scope=openid%20email%20https://www.googleapis.com/auth/userinfo.email

В соответствии с RFC 6749, клиенты ОБЯЗАТЕЛЬНО должны игнорировать неопознанные параметры ответа. На сервере необходимо подтвердить, что state , полученное от Google, соответствует токену сессии, созданному на шаге 1. Эта проверка в обоих направлениях помогает убедиться, что запрос отправляет пользователь, а не вредоносный скрипт.

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

PHP

Для использования этого примера необходимо загрузить клиентскую библиотеку Google API для PHP .

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
  return new Response('Invalid state parameter', 401);
}

Java

Для использования этого примера необходимо загрузить клиентскую библиотеку Google API для Java .

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if (!request.queryParams("state").equals(
    request.session().attribute("state"))) {
  response.status(401);
  return GSON.toJson("Invalid state parameter.");
}

Python

Для использования этого примера необходимо загрузить клиентскую библиотеку Google API для Python .

# Ensure that the request is not a forgery and that the user sending
# this connect request is the expected user.
if request.args.get('state', '') != session['state']:
  response = make_response(json.dumps('Invalid state parameter.'), 401)
  response.headers['Content-Type'] = 'application/json'
  return response

4. Обменяйте code на токен доступа и токен идентификации.

В ответе содержится параметр code — одноразовый код авторизации, который ваш сервер может обменять на токен доступа и токен идентификации. Ваш сервер осуществляет этот обмен, отправляя HTTPS POST запрос. POST запрос отправляется на конечную точку токена, которую вы должны получить из документа Discovery, используя значение метаданных token_endpoint . В дальнейшем предполагается, что конечная точка — https://oauth2.googleapis.com/token . Запрос должен содержать следующие параметры в теле POST :

Поля
code Код авторизации, возвращаемый при первоначальном запросе .
client_id Идентификатор клиента, который вы получаете из Cloud ConsoleClients pageкак описано в разделе «Получение учетных данных OAuth 2.0» .
client_secret Секретный ключ клиента, который вы получаете от Cloud ConsoleClients pageкак описано в разделе «Получение учетных данных OAuth 2.0» .
redirect_uri Авторизованный URI перенаправления для указанного client_id . Cloud ConsoleClients pageкак описано в разделе «Установка URI перенаправления» .
grant_type Это поле должно содержать значение authorization_code , как определено в спецификации OAuth 2.0 .

Фактический запрос может выглядеть примерно так:

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

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your-client-id&
client_secret=your-client-secret&
redirect_uri=https%3A//developers.google.com/oauthplayground&
grant_type=authorization_code

Успешный ответ на этот запрос содержит следующие поля в виде JSON-массива:

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

Это поле присутствует только в том случае, если параметр access_type был установлен в offline в запросе на аутентификацию . Подробнее см. раздел «Обновление токенов» .

5. Получите информацию о пользователе из токена идентификации.

Идентификационный токен (ID Token) — это JWT (JSON Web Token), то есть криптографически подписанный JSON-объект, закодированный в Base64. Обычно крайне важно проверить идентификационный токен перед его использованием, но поскольку вы взаимодействуете напрямую с Google по каналу HTTPS без посредников и используете свой секретный ключ клиента для аутентификации в Google, вы можете быть уверены, что полученный токен действительно получен от Google и является действительным. Если ваш сервер передает идентификационный токен другим компонентам вашего приложения, крайне важно, чтобы эти компоненты проверили токен перед его использованием.

Поскольку большинство API-библиотек объединяют проверку подлинности с декодированием значений, закодированных в base64url, и разбором JSON-данных, вам, вероятно, все равно придется проверять токен при доступе к утверждениям в ID-токене.

Полезная нагрузка идентификационного токена

Идентификационный токен — это JSON-объект, содержащий набор пар «имя/значение». Вот пример, отформатированный для удобства чтения:

{
  "iss": "https://accounts.google.com",
  "azp": "1234987819200.apps.googleusercontent.com",
  "aud": "1234987819200.apps.googleusercontent.com",
  "sub": "10769150350006150715113082367",
  "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
  "hd": "example.com",
  "email": "jsmith@example.com",
  "email_verified": "true",
  "iat": 1353601026,
  "exp": 1353604926,
  "nonce": "0394852-3190485-2490358"
}

Идентификационные токены Google могут содержать следующие поля (известные как утверждения ):

Требовать Предоставил Описание
aud всегда Целевая аудитория, для которой предназначен этот идентификационный токен. Это должен быть один из идентификаторов клиента OAuth 2.0 вашего приложения.
exp всегда Срок действия, по истечении которого токен ID не должен быть принят. Представлен в формате Unix epoch time (целые секунды).
iat всегда Время выдачи идентификационного токена. Представлено в формате Unix epoch time (целые секунды).
iss всегда Идентификатор отправителя ответа. Всегда https://accounts.google.com или accounts.google.com для токенов Google ID.
sub всегда Идентификатор пользователя, уникальный для всех учетных записей Google и никогда не используемый повторно. У одной учетной записи Google может быть несколько адресов электронной почты в разное время, но значение sub никогда не изменяется. Используйте sub в своем приложении в качестве уникального ключа-идентификатора пользователя. Максимальная длина — 255 символов ASCII с учетом регистра.
auth_time Время, когда произошла аутентификация пользователя, представляет собой число в формате JSON, обозначающее количество секунд, прошедших с момента начала эпохи Unix (1 января 1970 г., 00:00:00 UTC). Предоставляется, если поле auth_time включено в запрос на аутентификацию и активировано в настройках .
at_hash Хэш токена доступа. Обеспечивает проверку связи токена доступа с токеном идентификации. Если токен идентификации выдается со значением access_token в серверном потоке, это утверждение всегда включается. Это утверждение может использоваться в качестве альтернативного механизма защиты от атак межсайтовой подделки запросов, но при выполнении шагов 1 и 3 проверка токена доступа не требуется.
azp client_id авторизованного докладчика. Это поле необходимо только в том случае, если сторона, запрашивающая токен ID, не совпадает с аудиторией токена ID. Это может быть актуально для гибридных приложений Google, где веб-приложение и приложение Android имеют разные client_id OAuth 2.0, но используют один и тот же проект Google API.
email Адрес электронной почты пользователя. Предоставляется только в том случае, если вы указали область действия email в своем запросе. Значение этого утверждения может быть не уникальным для данной учетной записи и может меняться со временем, поэтому не следует использовать это значение в качестве основного идентификатора для связи с вашей записью пользователя. Вы также не можете полагаться на домен утверждения email для идентификации пользователей организаций Google Workspace или Cloud; используйте вместо него утверждение hd .
email_verified Возвращает true, если адрес электронной почты пользователя подтвержден; в противном случае — false.
family_name Фамилия пользователя. Может быть указана, если присутствует поле для указания name .
given_name Имя пользователя (или имя). Может быть указано, если присутствует поле для ввода name .
hd Домен, связанный с организацией Google Workspace или Google Cloud пользователя. Указывается только в том случае, если пользователь принадлежит к организации Google Cloud. Необходимо отметить этот пункт при ограничении доступа к ресурсу только для членов определенных доменов. Отсутствие этого пункта указывает на то, что учетная запись не принадлежит к домену, размещенному в Google.
locale Язык пользователя, представленный языковым тегом BCP 47. Может быть указан при наличии поля name .
name Полное имя пользователя в отображаемом виде. Может быть предоставлено в следующих случаях:
  • В область действия запроса входила строка "profile".
  • Идентификационный токен возвращается при обновлении токена.

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

nonce Значение одноразового числа nonce , предоставленного вашим приложением в запросе на аутентификацию. Для защиты от атак повторного воспроизведения следует предоставлять это значение только один раз.
picture URL-адрес фотографии профиля пользователя. Может быть указан в следующих случаях:
  • В область действия запроса входила строка "profile".
  • Идентификационный токен возвращается при обновлении токена.

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

profile URL страницы профиля пользователя. Может быть указан в следующих случаях:
  • В область действия запроса входила строка "profile".
  • Идентификационный токен возвращается при обновлении токена.

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

6. Аутентификация пользователя

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

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

Расширенные темы

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

Доступ к другим API Google

Одно из преимуществ использования OAuth 2.0 для аутентификации заключается в том, что ваше приложение может получить разрешение на использование других API Google от имени пользователя (например, YouTube, Google Drive, Календарь или Контакты) одновременно с аутентификацией пользователя. Для этого включите необходимые вам области действия (scope) в запрос на аутентификацию , который вы отправляете в Google. Например, чтобы добавить возрастную группу пользователя в запрос на аутентификацию, передайте параметр scope вида openid email https://www.googleapis.com/auth/profile.agerange.read . Пользователю будет предложено подтвердить согласие на соответствующем экране . Токен доступа, полученный от Google, позволит вашему приложению получить доступ ко всем API, связанным с запрошенными и предоставленными вам областями доступа.

Токены обновления

В запросе на доступ к API вы можете запросить получение токена обновления во время обмена code . Токен обновления обеспечивает вашему приложению непрерывный доступ к API Google, пока пользователь отсутствует в вашем приложении. Чтобы запросить токен обновления, установите параметр access_type в offline в вашем запросе на аутентификацию .

Соображения:

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

Для получения дополнительной информации см. раздел «Обновление токена доступа (автономный доступ)» .

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

Для получения более подробной информации о параметре prompt см. prompt в таблице параметров URI аутентификации .

Параметры URI аутентификации

В таблице ниже приведено более полное описание параметров, принимаемых API аутентификации OAuth 2.0 от Google.

Параметр Необходимый Описание
client_id (Необходимый) Идентификатор клиента, который вы получаете из Cloud ConsoleClients pageкак описано в разделе «Получение учетных данных OAuth 2.0» .
nonce (Необходимый) Случайное значение, сгенерированное вашим приложением, которое обеспечивает защиту от повторного воспроизведения.
response_type (Необходимый) Если значение равно code , запускается базовый поток авторизации с использованием кода, требующий POST на конечную точку токена для получения токенов. Если значение равно token id_token или id_token token , запускается неявный поток , требующий использования JavaScript на URI перенаправления для получения токенов из URI #fragment identifier .
redirect_uri (Необходимый) Определяет, куда отправляется ответ. Значение этого параметра должно точно совпадать с одним из разрешенных значений перенаправления, которые вы задали в настройках. Cloud ConsoleClients page (включая схему HTTP или HTTPS, регистр и завершающий символ '/', если таковой имеется).
scope (Необходимый)

Параметр scope должен начинаться со значения openid , а затем включать значение profile , значение email или оба значения.

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

Если значение параметра email присутствует, то токен ID включает в себя утверждения email и email_verified .

Помимо этих специфических для OpenID областей действия, ваш аргумент scope может также включать другие значения scope. Все значения scope должны быть разделены пробелами. Например, если вам нужен доступ к каждому файлу в Google Диск пользователя, ваш параметр scope может выглядеть так: openid profile email https://www.googleapis.com/auth/drive.file .

Для получения информации о доступных областях действия см. раздел «Области действия OAuth 2.0 для API Google» или документацию к тому API Google, который вы хотите использовать.

state (Необязательно, но настоятельно рекомендуется)

Непрозрачная строка, которая передается по протоколу туда и обратно; то есть она возвращается в качестве параметра URI в базовом потоке и в качестве идентификатора #fragment URI в неявном потоке.

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

access_type (Необязательный) Допустимые значения: offline и online . Эффект описан в разделе «Доступ в автономном режиме» ; если запрашивается токен доступа, клиент не получает токен обновления, если не указано значение offline .
claims (Необязательный) Параметр claims используется для указания одного или нескольких необязательных полей, которые следует включить в конечную точку userinfo или в ответ на запрос аутентификации с токеном идентификатора. Значение представляет собой объект JSON, содержащий тип ответа и запрошенные утверждения. Серверы Google принимают следующие запросы утверждений:
Запросы на возмещение расходов
auth_time Запросите время последней аутентификации пользователя. Чтобы вернуть auth_time в качестве поля в ответе на запрос ID-токена, добавьте параметр запроса claims : claims={"id_token":{"auth_time":{"essential":true}}} Необходимо включить в настройках .
display (Необязательный) Строковое значение ASCII, указывающее, как сервер авторизации отображает страницы пользовательского интерфейса аутентификации и согласия. Следующие значения задаются и принимаются серверами Google, но не влияют на поведение протокола: page , popup , touch и wap .
hd (Необязательный)

Оптимизируйте процесс входа в систему для учетных записей, принадлежащих организации Google Cloud. Указав домен организации Google Cloud (например, mycollege.edu ), вы можете указать, что интерфейс выбора учетной записи должен быть оптимизирован для учетных записей этого домена. Чтобы оптимизировать процесс для учетных записей организации Google Cloud в целом, а не только для одного домена организации Google Cloud, установите значение звездочки ( * ): hd=* .

Не полагайтесь на эту оптимизацию пользовательского интерфейса для контроля доступа к вашему приложению, поскольку запросы на стороне клиента могут быть изменены. Убедитесь , что возвращаемый токен ID содержит значение hd claim, соответствующее вашим ожиданиям (например, mycolledge.edu ). В отличие от параметра запроса, значение hd claim токена ID содержится в токене безопасности от Google, поэтому этому значению можно доверять.

include_granted_scopes (Необязательный) Если этому параметру присвоено значение true , и запрос на авторизацию одобрен, авторизация будет включать любые предыдущие авторизации, предоставленные данной комбинации пользователь/приложение для других областей действия; см. Инкрементальная авторизация .

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

login_hint (Необязательный) Когда ваше приложение знает, какого пользователя оно пытается аутентифицировать, оно может передать этот параметр в качестве подсказки серверу аутентификации. Передача этой подсказки подавляет выбор учетной записи и либо автоматически заполняет поле электронной почты в форме входа, либо выбирает правильную сессию (если пользователь использует несколько учетных записей ), что может помочь избежать проблем, возникающих, если ваше приложение входит в систему под неправильной учетной записью пользователя. Значением может быть либо адрес электронной почты, либо sub , эквивалентная идентификатору Google пользователя.
prompt (Необязательный) Список строковых значений, разделённых пробелами, указывающий, запрашивает ли сервер авторизации у пользователя повторную аутентификацию и согласие. Возможные значения:
  • none

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

  • consent

    Сервер авторизации запрашивает у пользователя согласие перед тем, как вернуть информацию клиенту.

  • select_account

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

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

hl (Необязательный) Языковой тег BCP 47 , используемый для указания языка отображения экранов входа в систему, выбора учетной записи и согласия. Если этот параметр не указан, по умолчанию используется язык учетной записи Google пользователя или настройки браузера. Например, чтобы запросить пользовательский интерфейс на британском английском языке, установите параметр в en-GB .

Проверка идентификационного токена

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

Ниже перечислены распространенные ситуации, в которых вы можете отправлять идентификационные токены на свой сервер:

  • Отправка идентификационных токенов вместе с запросами, требующими аутентификации. Идентификационные токены указывают конкретного пользователя, отправившего запрос, и для какого клиента был выдан данный токен.

Идентификационные токены являются конфиденциальной информацией и могут быть использованы не по назначению в случае перехвата. Необходимо обеспечить безопасную обработку этих токенов, передавая их только по протоколу HTTPS и используя только данные POST или в заголовках запросов. Если вы храните идентификационные токены на своем сервере, вы также должны хранить их в безопасном месте.

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

Проверка идентификационного токена включает в себя несколько этапов:

  1. Убедитесь, что токен ID правильно подписан эмитентом. Токены, выданные Google, подписываются с использованием одного из сертификатов, найденных по URI, указанному в значении метаданных jwks_uri документа Discovery .
  2. Убедитесь, что значение поля iss в токене ID равно https://accounts.google.com или accounts.google.com .
  3. Убедитесь, что значение поля aud в токене ID совпадает с идентификатором клиента вашего приложения.
  4. Убедитесь, что срок действия ( exp claim) ID-токена не истек.
  5. Если вы указали значение параметра hd в запросе, убедитесь, что токен ID содержит утверждение hd , соответствующее принятому домену, связанному с организацией Google Cloud.

Шаги со 2 по 5 включают только сравнение строк и дат, что довольно просто, поэтому мы не будем подробно их описывать.

Первый шаг более сложный и включает проверку криптографической подписи. В целях отладки вы можете использовать конечную точку Google tokeninfo для сравнения с локальной обработкой, реализованной на вашем сервере или устройстве. Предположим, значение вашего ID-токена равно XYZ123 . Тогда вам нужно будет разыменовать URI https://oauth2.googleapis.com/tokeninfo?id_token= XYZ123 . Если подпись токена действительна, ответом будет полезная нагрузка JWT в декодированном виде объекта JSON.

Конечная точка tokeninfo полезна для отладки, но для производственных целей лучше получать открытые ключи Google из конечной точки keys и выполнять проверку локально. URI ключей следует получать из документа Discovery, используя значение метаданных jwks_uri . Запросы к конечной точке отладки могут быть ограничены или подвержены периодическим ошибкам.

Поскольку Google редко меняет свои открытые ключи, вы можете кэшировать их, используя директивы кэширования HTTP-ответа, и в подавляющем большинстве случаев выполнять локальную проверку гораздо эффективнее, чем с помощью конечной точки tokeninfo . Эта проверка требует получения и анализа сертификатов, а также выполнения соответствующих криптографических вызовов для проверки подписи. К счастью, для этого существуют хорошо отлаживаемые библиотеки на самых разных языках программирования (см. jwt.io ).

Получение информации из профиля пользователя

Для получения дополнительной информации о профиле пользователя можно использовать токен доступа (который ваше приложение получает в процессе аутентификации ) и стандарт OpenID Connect :

  1. Для соответствия стандарту OpenID необходимо включить значения области действия openid profile в запрос на аутентификацию .

    Если вы хотите, чтобы в запрос на аутентификацию был включен адрес электронной почты пользователя, вы можете указать дополнительное значение параметра scope для email . Чтобы указать и profile , и email , вы можете включить следующий параметр в URI запроса на аутентификацию:

    scope=openid%20profile%20email
  2. Add your access token to the authorization header and make an HTTPS GET request to the userinfo endpoint, which you should retrieve from the Discovery document using the userinfo_endpoint metadata value. The userinfo response includes information about the user, as described in OpenID Connect Standard Claims and the claims_supported metadata value of the Discovery document. Users or their organizations may choose to supply or withhold certain fields, so you might not get information for every field for your authorized scopes of access.

The Discovery document

The OpenID Connect protocol requires the use of multiple endpoints for authenticating users, and for requesting resources including tokens, user information, and public keys.

To simplify implementations and increase flexibility, OpenID Connect allows the use of a "Discovery document," a JSON document found at a well-known location containing key-value pairs which provide details about the OpenID Connect provider's configuration, including the URIs of the authorization, token, revocation, userinfo, and public-keys endpoints. The Discovery document for Google's OpenID Connect service may be retrieved from:

https://accounts.google.com/.well-known/openid-configuration

To use Google's OpenID Connect services, you should hard-code the Discovery-document URI ( https://accounts.google.com/.well-known/openid-configuration ) into your application. Your application fetches the document, applies caching rules in the response, then retrieves endpoint URIs from it as needed. For example, to authenticate a user, your code would retrieve the authorization_endpoint metadata value ( https://accounts.google.com/o/oauth2/v2/auth in the example below) as the base URI for authentication requests that are sent to Google.

Here is an example of such a document; the field names are those specified in OpenID Connect Discovery 1.0 (refer to that document for their meanings). The values are purely illustrative and might change, although they are copied from a recent version of the actual Google Discovery document:

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "code token",
    "code id_token",
    "token id_token",
    "code token id_token",
    "none"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "scopes_supported": [
    "openid",
    "email",
    "profile"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic"
  ],
  "claims_supported": [
    "aud",
    "email",
    "email_verified",
    "exp",
    "family_name",
    "given_name",
    "iat",
    "iss",
    "locale",
    "name",
    "picture",
    "sub"
  ],
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ]
}

You may be able to avoid an HTTP round-trip by caching the values from the Discovery document. Standard HTTP caching headers are used and should be respected.

Клиентские библиотеки

The following client libraries make implementing OAuth 2.0 simpler by integrating with popular frameworks:

OpenID Connect compliance

Google's OAuth 2.0 authentication system supports the required features of the OpenID Connect Core specification. Any client which is designed to work with OpenID Connect should interoperate with this service (with the exception of the OpenID Request Object ).