OpenID Connect

Конечная точка Google OpenID Connect сертифицирована 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 для входа в систему, вам необходимо настроить проект в чтобы получить учетные данные OAuth 2.0, установите URI перенаправления и (необязательно) настройте информацию о брендинге, которую ваши пользователи видят на экране согласия пользователя. Вы также можете использовать для создания сервисной учетной записи, включения биллинга, настройки фильтрации и выполнения других задач. Более подробную информацию см. Помощь .

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

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

Установите URI перенаправления

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

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

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

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

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

Снимок экрана страницы согласия

Доступ к услуге

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

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

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

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

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

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

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

Убедитесь, что вы настроили свое приложение в чтобы позволить ему использовать эти протоколы и аутентифицировать ваших пользователей. Когда пользователь пытается войти в систему через 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
));

Ява

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

Питон

Чтобы использовать этот пример, вам необходимо загрузить клиентскую библиотеку 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 , который вы получаете из .
  • response_type , который в базовом запросе потока кода авторизации должен быть code . (Подробнее читайте на response_type .)
  • scope , которая в базовом запросе должна быть openid email . (Подробнее читайте в scope ».)
  • redirect_uri должен быть конечной точкой HTTP на вашем сервере, которая получит ответ от Google. Значение должно точно совпадать с одним из авторизованных URI перенаправления для клиента OAuth 2.0, который вы настроили в разделе . Если это значение не соответствует авторизованному URI, запрос завершится с ошибкой redirect_uri_mismatch .
  • state должно включать значение уникального токена сеанса защиты от подделки, а также любую другую информацию, необходимую для восстановления контекста, когда пользователь возвращается в ваше приложение, например, начальный URL-адрес. (Подробнее читайте на state .)
  • nonce — это случайное значение, генерируемое вашим приложением, которое включает защиту от повтора, если она присутствует.
  • login_hint может быть адресом электронной почты пользователя или sub , эквивалентной идентификатору Google ID пользователя. Если вы не предоставляете 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//oauth2.example.com/code&
 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://oauth2.example.com/code?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

На сервере вы должны подтвердить, что 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);
}

Ява

Чтобы использовать этот пример, необходимо загрузить клиентскую библиотеку 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.");
}

Питон

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

Поля
code Код авторизации, возвращаемый из первоначального запроса .
client_id Идентификатор клиента, который вы получаете от , как описано в разделе Получение учетных данных OAuth 2.0 .
client_secret Секрет клиента, который вы получаете от , как описано в разделе Получение учетных данных OAuth 2.0 .
redirect_uri Авторизованный URI перенаправления для данного client_id , указанного в , как описано в разделе Установка 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//oauth2.example.com/code&
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 всегда Идентификатор эмитента эмитента ответа. Всегда https://accounts.google.com или accounts.google.com для токенов Google ID.
sub всегда Идентификатор пользователя, уникальный среди всех учетных записей Google и никогда не используемый повторно. Учетная запись Google может иметь несколько адресов электронной почты в разные моменты времени, но sub значение никогда не меняется. Используйте sub в своем приложении в качестве ключа уникального идентификатора пользователя. Максимальная длина — 255 символов ASCII с учетом регистра.
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, если адрес электронной почты пользователя подтвержден; в противном случае ложь.
family_name Фамилия(и) или фамилия(я) пользователя. Может быть предоставлено при наличии заявки name .
given_name Имя(я) или имя(а) пользователя. Может быть предоставлено при наличии заявки name .
hd Домен, связанный с организацией Google Workspace или Cloud пользователя. Предоставляется только в том случае, если пользователь принадлежит к организации Google Cloud. Вы должны проверить это утверждение, если доступ к ресурсу разрешен только членам определенных доменов. Отсутствие этого утверждения указывает на то, что учетная запись не принадлежит домену, размещенному в Google.
locale Языковой стандарт пользователя, представленный языковым тегом BCP 47 . Может быть предоставлено при наличии заявки name .
name Полное имя пользователя в отображаемой форме. Может быть предоставлено, когда:
  • Область запроса включала строку «профиль».
  • Токен идентификатора возвращается после обновления токена.

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

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

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

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

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

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

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

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

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

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

Доступ к другим 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, пока пользователь отсутствует в вашем приложении. Чтобы запросить токен обновления, добавьте в запросе аутентификации значение offline для параметра access_type .

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

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

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

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

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

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

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

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

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

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

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

В дополнение к этим специфичным для OpenID областям ваш аргумент области может также включать другие значения области. Все значения области должны быть разделены пробелами. Например, если вам нужен пофайловый доступ к Google Диску пользователя, параметром области действия может быть 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 Access ; если запрашивается токен доступа, клиент не получает токен обновления, если не указано значение offline .
display (Необязательный) Строковое значение ASCII, определяющее, как сервер авторизации отображает страницы пользовательского интерфейса аутентификации и согласия. Следующие значения указаны и принимаются серверами Google, но не влияют на его поведение: page , popup , touch и wap .
hd (Необязательный)

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

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

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

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

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

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

  • consent

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

  • select_account

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

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

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

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

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

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

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

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

Проверка идентификационного токена требует нескольких шагов:

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

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

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

Конечная точка tokeninfo полезна для отладки, но для производственных целей необходимо получить открытые ключи Google из конечной точки ключей и выполнить проверку локально. Вам следует получить 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, который вы должны получить из документа Discovery, используя значение метаданных userinfo_endpoint . Ответ userinfo включает информацию о пользователе, как описано в OpenID Connect Standard Claims и значении claims_supported документа 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 (их значения см. в этом документе). Значения являются чисто иллюстративными и могут измениться, хотя они скопированы из последней версии фактического документа Google Discovery:

{
  "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 запроса ).

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

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

Настройка OAuth 2.0

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

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

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

Установите URI перенаправления

Перенаправление URI, которое вы установили в Определяет, где Google отправляет ответы на ваши запросы на аутентификацию .

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

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

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

В следующем диалоговом окне «Согласие» показано, что пользователь увидит, когда в запросе присутствует комбинация OAuth 2.0 и Google Drive Scopes. (Этот общий диалог был сгенерирован с использованием Playground Google OAuth 2.0 , поэтому он не включает информацию о брендинге, которая будет установлена ​​в .)

Снимок экрана страницы согласия

Доступ к услуге

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

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

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

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

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

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

Сервер поток

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

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

1. Создайте жетон антифоргического состояния

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

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

Следующий код демонстрирует создание уникальных токенов сеанса.

PHP

Вы должны загрузить клиентскую библиотеку Google APIS для 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
));

Ява

Вы должны загрузить клиентскую библиотеку Google APIS для 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);

Питон

Вы должны загрузить клиентскую библиотеку Google APIS для 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

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

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

  • client_id , который вы получаете от .
  • response_type , который в базовом запросе кода авторизации должен быть code . (Подробнее читайте на response_type .)
  • scope , которая в основном запросе должна быть openid email . (Подробнее читайте в scope .)
  • redirect_uri должен быть конечной точкой HTTP на вашем сервере, которая получит ответ от Google. Значение должно точно соответствовать одному из авторизованных перенаправленных URI для клиента OAuth 2.0, который вы настроили в . Если это значение не соответствует авторизованному URI, запрос выйдет из строя с ошибкой redirect_uri_mismatch .
  • state должно включать ценность уникального сессионного токена антифоргии, а также любую другую информацию, необходимую для восстановления контекста, когда пользователь возвращается в ваше приложение, например, начальный URL. (Подробнее читайте в state .)
  • nonce - это случайное значение, сгенерированное вашим приложением, которое обеспечивает защиту воспроизведения при наличии.
  • login_hint может быть адрес электронной почты пользователя или sub , которая эквивалентна идентификатору Google пользователя. Если вы не предоставите login_hint , и пользователь в настоящее время входит в систему, экран согласия включает в себя запрос на одобрение, чтобы выпустить адрес электронной почты пользователя в вашем приложении. (Подробнее читайте на login_hint .)
  • Используйте параметр hd , чтобы оптимизировать поток OpenID Connect для пользователей конкретного домена, связанного с рабочей пространством Google или облачной организации (Подробнее на 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//oauth2.example.com/code&
 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://oauth2.example.com/code?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

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

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

PHP

Вы должны загрузить клиентскую библиотеку Google APIS для 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);
}

Ява

Вы должны загрузить клиентскую библиотеку Google APIS для 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.");
}

Питон

Вы должны загрузить клиентскую библиотеку Google APIS для 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 Идентификатор клиента, который вы получаете от , как описано в получении учетных данных OAuth 2.0 .
client_secret Секрет клиента, который вы получаете от , как описано в получении учетных данных OAuth 2.0 .
redirect_uri Авторизованный uRI перенаправления для данного client_id , указанного в , как описано в SET A 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//oauth2.example.com/code&
grant_type=authorization_code

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

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

Это поле присутствует только в том случае, если параметр access_type был установлен на offline в запросе аутентификации . Для получения подробной информации см. Trown Token .

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

Токен для ID-это JWT (JSON Web Token), то есть криптографически подписанный объект 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 ID могут содержать следующие поля (известные как претензии ):

Требовать Предоставил Описание
aud всегда Аудитория, для которой предназначен этот жетон идентификатора. Это должен быть один из идентификаторов клиента OAuth 2.0 вашего приложения.
exp всегда Время истечения срока или после того, как токен идентификатора не должен быть принят. Представлено во времени Unix (целые секунды).
iat всегда Время, когда жетон идентификатор был выпущен. Представлено во времени Unix (целые секунды).
iss всегда Идентификатор эмитента для эмитента ответа. Всегда https://accounts.google.com или accounts.google.com для токенов Google ID.
sub всегда Идентификатор для пользователя, уникальный среди всех учетных записей Google и никогда не использовался повторно. Учетная запись Google может иметь несколько адресов электронной почты в разные моменты времени, но sub значение никогда не изменяется. Используйте sub в вашем приложении в качестве ключа с уникальным идентификатором для пользователя. Максимальная длина 255 чувствительных к случаям символов ASCII.
at_hash Доступ к токену. Обеспечивает проверку того, что токен доступа связан с токеном идентификации. Если токен идентификатора выдается с значением access_token в потоке серверов, эта претензия всегда включена. Это требование может использоваться в качестве альтернативного механизма для защиты от атак по перекрестному запросу, но если вы следите за шагом 1 и шагом 3, нет необходимости проверять токен доступа.
azp client_id уполномоченного докладчика. Это утверждение необходимо только тогда, когда сторона, запрашивающая токен идентификатора, не совпадает с аудиторией идентификационного токена. Это может иметь место в Google для гибридных приложений, где веб -приложение и приложение для Android имеют другой OAuth 2.0 client_id , но поделитесь одним и тем же проектом Google APIS.
email Адрес электронной почты пользователя. Предоставлено только в том случае, если вы включили сферу email в ваш запрос. Значение этой претензии не может быть уникальной для этой учетной записи и может измениться со временем, поэтому вы не должны использовать это значение в качестве основного идентификатора для ссылки на вашу запись пользователя. Вы также не можете полагаться на домен заявления о email , чтобы идентифицировать пользователей Google Workspace или облачных организаций; Вместо этого используйте заявление hd .
email_verified Верно, если адрес электронной почты пользователя был проверен; в противном случае ложь.
family_name Фамилия пользователя или фамилия (ы). Может быть предоставлен, когда присутствует требование name .
given_name Имя (ы) пользователя или имя (ы). Может быть предоставлен, когда присутствует требование name .
hd Домен, связанный с рабочей пространством Google или облачной организацией пользователя. Предоставлено только в том случае, если пользователь принадлежит к облачной организации Google. Вы должны проверить это утверждение при ограничении доступа к ресурсу только для членов определенных доменов. Отсутствие этой претензии указывает на то, что учетная запись не принадлежит к домену с размещенным Google.
locale Локаль пользователя, представленный языком BCP 47 . Может быть предоставлен, когда присутствует требование name .
name Полное имя пользователя в отображаемой форме. Может быть предоставлено, когда:
  • Сфера запроса включала строку «профиль»
  • Токен идентификатора возвращается из обновления токена

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

nonce Стоимость nonce предоставленного вашим приложением в запросе аутентификации. Вы должны обеспечить защиту от атак повтор, гарантируя, что она представлена ​​только один раз.
picture URL -адрес изображения профиля пользователя. Может быть предоставлено, когда:
  • Сфера запроса включала строку «профиль»
  • Токен идентификатора возвращается из обновления токена

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

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

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

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

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

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

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

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

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

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

Обновлять токены

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

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

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

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

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

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

Аутентификация параметров URI

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

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

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

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

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

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

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

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

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

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

access_type (Необязательный) Разрешенные значения offline и online . Эффект задокументирован в автономном доступе ; Если запрашивается токен доступа, клиент не получает токен обновления, если не указано значение offline .
display (Необязательный) Значение строки ASCII для определения того, как сервер авторизации отображает страницы пользовательского интерфейса аутентификации и согласиться. Следующие значения указаны и принимаются серверами Google, но не оказывают никакого влияния на его поведение: page , popup , touch и wap .
hd (Необязательный)

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

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

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

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

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

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

  • consent

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

  • select_account

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

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

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

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

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

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

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

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

Проверка токена идентификатора требует нескольких шагов:

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

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

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

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

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

  1. Чтобы быть OpenID, вы должны включить значения объема openid profile в ваш запрос на аутентификацию .

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

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

Документ Discovery

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

Чтобы упростить реализации и повысить гибкость, OpenID Connect позволяет использовать «Discovery Document», документ JSON, найденный в хорошо известном месте, содержащем пары ключевых значений, которые предоставляют подробную информацию о конфигурации поставщика OpenID Connect, включая URIS авторизации , токен, отзыв, пользовательский и общепринятые конечные точки. Документ Discovery для службы Google OpenID Connect может быть извлечен из:

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

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

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

{
  "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 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 ).