OpenID Connect

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

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

Настройка OAuth 2.0

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

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

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

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

Вы также можете посмотреть идентификатор клиента и секретный код клиента на странице Clients (Клиенты) в Cloud Console.

  1. Перейдите на страницу Клиенты.
  2. Нажмите на название клиента или на значок карандаша (). Идентификатор клиента и секретный код находятся в верхней части страницы.

Как настроить URI перенаправления

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

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

  1. Перейдите на страницу Клиенты.
  2. Нажмите на клиента.
  3. Посмотрите или измените URI переадресации.

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

Как настроить окно запроса доступа

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

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

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

  1. Откройте страницу брендинга в консоли Google Cloud.
  2. Выберите существующий проект или создайте новый.
  3. Заполните форму и нажмите Сохранить.

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

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

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

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

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

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

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

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

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

Процесс на сервере

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

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

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

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

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

В приведенном ниже коде показано, как генерировать уникальные токены сеансов.

PHP

Чтобы использовать этот пример, необходимо скачать клиентскую библиотеку API Google для 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

Чтобы использовать этот пример, необходимо скачать клиентскую библиотеку API Google для 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

Чтобы использовать этот пример, необходимо скачать клиентскую библиотеку API Google для 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 Console.
  • response_type, которое в базовом запросе на обработку кода авторизации должно быть code. Подробнее: response_type.
  • scope, которое в базовом запросе должно быть равно openid email. Подробнее: scope.
  • redirect_uri – это конечная точка HTTP на вашем сервере, которая будет получать ответ от Google. Значение должно точно совпадать с одним из авторизованных URI перенаправления для клиента OAuth 2.0, который вы настроили на странице "Учетные данные" в Cloud Console. Если это значение не совпадает с авторизованным 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

Чтобы использовать этот пример, необходимо скачать клиентскую библиотеку API Google для 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

Чтобы использовать этот пример, необходимо скачать клиентскую библиотеку API Google для 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

Чтобы использовать этот пример, необходимо скачать клиентскую библиотеку API Google для 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 отправляется в конечную точку токена, которую необходимо получить из документа обнаружения, используя значение метаданных token_endpoint. В приведенном ниже примере используется конечная точка https://oauth2.googleapis.com/token. В теле POST запроса должны быть указаны следующие параметры:

Поля
code Код авторизации, возвращенный в ответ на первоначальный запрос.
client_id Идентификатор клиента, который вы получили на странице Clients (Клиенты) в Cloud Console, как описано в разделе Получение учетных данных OAuth 2.0.
client_secret Секретный код клиента, который вы получили на странице клиентов в Cloud Console, как описано в разделе Получение учетных данных OAuth 2.0.
redirect_uri Авторизованный URI переадресации для указанного client_id, заданный на странице клиентов в Cloud Console, как описано в разделе Как задать 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. Как получить информацию о пользователе из токена идентификатора

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

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

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

Токен идентификации – это объект 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 Всегда Время, после которого токен идентификатора не должен приниматься. Указывается в формате Unix-времени (целое число секунд).
iat Всегда Время выпуска токена идентификации. Указывается в формате Unix-времени (целое число секунд).
iss Всегда Идентификатор эмитента, отправившего ответ. Для токенов идентификации Google всегда используется значение https://accounts.google.com или accounts.google.com.
sub Всегда Идентификатор пользователя, уникальный для всех аккаунтов Google и никогда не используемый повторно. В разное время с аккаунтом Google могут быть связаны разные адреса электронной почты, но значение sub никогда не меняется. Используйте sub в своем приложении в качестве уникального идентификатора пользователя. Максимальная длина – 255 символов ASCII с учетом регистра.
amr Массив JSON со строками, которые идентифицируют способы аутентификации, используемые для входа в аккаунт Google. Если присутствует, включает одно или несколько из следующих возможных значений [IANA.AMR]:
  • Использован аппаратный ключ hwk
  • mfa Многофакторная аутентификация выполнена
  • pwd использован пароль
  • sms для подтверждения использовалось SMS-сообщение.
  • swk Использовался программный ключ, например ключ доступа.
  • tel подтверждение по телефону
Присутствует, только если утверждение amr включено в запрос на аутентификацию и активировано в настройках.
auth_time Время, когда была выполнена аутентификация пользователя. Число JSON, представляющее количество секунд, прошедших с начала эпохи Unix (00:00:00 1 января 1970 года по всемирному координированному времени). Предоставляется, если утверждение auth_time включено в запрос на аутентификацию и активировано в настройках.
at_hash Хеш токена доступа. Подтверждает, что токен доступа связан с токеном идентификации. Если токен идентификатора выпущен со значением access_token в потоке сервера, это утверждение всегда включается. Это утверждение можно использовать в качестве альтернативного механизма защиты от атак с межсайтовой подделкой запросов, но если вы выполните шаг 1 и шаг 3, проверять токен доступа не потребуется.
azp client_id уполномоченного представителя. Это утверждение необходимо, только если сторона, запрашивающая токен идентификатора, не совпадает с аудиторией токена идентификатора. Например, в Google это может произойти с гибридными приложениями, когда у веб-приложения и приложения для Android разные client_id OAuth 2.0, но один и тот же проект API Google.
email Адрес электронной почты пользователя. Предоставляется, только если в запрос включена область действия email. Значение этого утверждения может быть неуникальным для аккаунта и со временем меняться, поэтому не используйте его в качестве основного идентификатора для связи с записью пользователя. Вы также не можете полагаться на домен утверждения email для идентификации пользователей Google Workspace или организаций Cloud. Вместо этого используйте утверждение hd.
email_verified True, если адрес электронной почты пользователя подтвержден; в противном случае – false.
family_name Фамилия пользователя. Может предоставляться, если есть утверждение name.
given_name Имя или имена пользователя. Может предоставляться, если есть утверждение name.
hd Домен, связанный с организацией Google Workspace или Cloud, к которой относится пользователь. Предоставляется, только если пользователь принадлежит к организации Google Cloud. Это утверждение необходимо проверять, когда доступ к ресурсу предоставляется только участникам определенных доменов. Отсутствие этого утверждения указывает на то, что аккаунт не принадлежит домену, размещенному в Google.
locale Региональные настройки пользователя, представленные тегом языка BCP 47. Может предоставляться, если есть утверждение name.
name Полное имя пользователя в формате, подходящем для отображения. Может предоставляться в следующих случаях:
  • Область действия запроса включала строку "profile".
  • Токен идентификатора возвращается при обновлении токена.

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

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

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

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

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

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

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

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

Дополнительные темы

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

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

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

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

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

Что необходимо учитывать

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

Подробнее о том, как обновить токен доступа (офлайн-режим)…

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

Подробную информацию о параметре prompt можно найти в разделе prompt таблицы Параметры URI аутентификации.

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

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

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

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

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

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

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

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

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

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

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

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

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

Не полагайтесь на эту оптимизацию интерфейса для управления доступом к приложению, поскольку клиентские запросы можно изменить. Обязательно проверьте, что значение утверждения hd в возвращенном токене идентификации соответствует ожидаемому (например, mycolledge.edu). В отличие от параметра запроса, утверждение hd токена идентификации содержится в токене безопасности от 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. Убедитесь, что токен идентификатора правильно подписан эмитентом. Токены, выпущенные Google, подписываются с помощью одного из сертификатов, которые можно найти по URI, указанному в значении метаданных jwks_uri документа обнаружения.
  2. Убедитесь, что значение утверждения iss в токене идентификации равно https://accounts.google.com или accounts.google.com.
  3. Убедитесь, что значение утверждения aud в токене идентификатора совпадает с идентификатором клиента вашего приложения.
  4. Убедитесь, что срок действия (утверждение exp) токена идентификации не истек.
  5. Если в запросе указано значение параметра hd, убедитесь, что токен идентификатора содержит утверждение hd, соответствующее принятому домену, связанному с организацией Google Cloud.

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

Первый шаг сложнее и включает проверку криптографической подписи. Для отладки можно использовать конечную точку Google tokeninfo, чтобы сравнить результаты с локальной обработкой на вашем сервере или устройстве. Предположим, что значение токена идентификатора – 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.

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

    scope=openid%20profile%20email
    
  2. Добавьте токен доступа в заголовок авторизации и отправьте HTTPS-запрос GET к конечной точке userinfo, которую нужно получить из документа обнаружения, используя значение метаданных userinfo_endpoint. Ответ userinfo содержит информацию о пользователе, как описано в OpenID Connect Standard Claims и значении метаданных claims_supported в документе Discovery. Пользователи или их организации могут предоставлять или скрывать определенные поля, поэтому вы можете не получить информацию для каждого поля в разрешенных областях доступа.

Документ Discovery

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

Чтобы упростить реализацию и повысить гибкость, OpenID Connect позволяет использовать discovery-документ – документ JSON, который находится в известном месте и содержит пары "ключ-значение" с информацией о конфигурации поставщика OpenID Connect, включая URI конечных точек авторизации, токена, отзыва, информации о пользователе и открытых ключей. Discovery-документ для сервиса Google OpenID Connect можно получить по следующему адресу:

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

Чтобы использовать сервисы Google OpenID Connect, необходимо жестко закодировать URI discovery-документа (https://accounts.google.com/.well-known/openid-configuration) в приложении. Приложение получает документ, применяет правила кеширования в ответе, а затем извлекает из него URI конечных точек по мере необходимости. Например, чтобы выполнить аутентификацию пользователя, ваш код должен получить значение метаданных authorization_endpoint (https://accounts.google.com/o/oauth2/v2/auth в примере ниже) в качестве базового URI для запросов аутентификации, отправляемых в Google.

Ниже приведен пример такого документа. Названия полей соответствуют спецификации OpenID Connect Discovery 1.0 (их значения можно найти в этом документе). Значения приведены исключительно в качестве примера и могут меняться, хотя они скопированы из недавней версии реального discovery-документа рекомендаций Google:

{
  "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"
  ]
}

Чтобы избежать HTTP-запроса, можно кешировать значения из документа Discovery. Используются стандартные заголовки кеширования HTTP, которые необходимо соблюдать.

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

Следующие клиентские библиотеки упрощают реализацию OAuth 2.0 за счет интеграции с популярными фреймворками:

Соответствие OpenID Connect

Система аутентификации Google OAuth 2.0 поддерживает обязательные функции спецификации OpenID Connect Core. Любой клиент, предназначенный для работы с OpenID Connect, должен взаимодействовать с этим сервисом (за исключением объекта запроса OpenID).