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

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

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

To view the client ID and client secret for a given OAuth 2.0 credential, click the following text: Select credential. In the window that opens, choose your project and the credential you want, then click View.

Or, view your client ID and client secret from the Credentials page in API Console:

  1. Go to the Credentials page.
  2. Click the name of your credential or the pencil () icon. Your client ID and secret are at the top of the page.

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

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

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

  1. Go to the Credentials page.
  2. В разделе идентификаторов клиентов OAuth 2.0 на странице щелкните учетные данные.
  3. Просмотр или редактирование URI перенаправления.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  1. Создайте токен состояния защиты от подделки
  2. Отправить запрос аутентификации в Google
  3. Подтвердите токен состояния защиты от подделки
  4. code обмена для токена доступа и токена ID
  5. Получить информацию о пользователе из токена ID
  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
));

Ява

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

питон

Чтобы использовать этот образец, необходимо загрузить клиентскую библиотеку 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 из документа обнаружения , используя значение метаданных authorization_endpoint точки. В следующем обсуждении предполагается, что базовый URI — https://accounts.google.com/o/oauth2/v2/auth .

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

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

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

Ява

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

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

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

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

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

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your-client-id&
client_secret=your-client-secret&
redirect_uri=https%3A//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 . Дополнительные сведения см. в разделе Обновить токены .

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

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

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

Полезная нагрузка токена ID

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

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

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

Требовать При условии Описание
aud всегда Аудитория, для которой предназначен этот идентификатор. Это должен быть один из идентификаторов клиента OAuth 2.0 вашего приложения.
exp всегда Время истечения срока действия, по истечении которого токен ID не должен приниматься. Представлено во времени Unix (целые секунды).
iat всегда Время выпуска токена ID. Представлено во времени Unix (целые секунды).
iss всегда Идентификатор эмитента для эмитента ответа. Всегда https://accounts.google.com или accounts.google.com для токенов Google ID.
sub всегда Идентификатор пользователя, уникальный среди всех учетных записей Google и никогда не используемый повторно. Аккаунт Google может иметь несколько адресов электронной почты в разные моменты времени, но sub значение никогда не меняется. Используйте sub в своем приложении в качестве ключа уникального идентификатора для пользователя. Максимальная длина 255 символов ASCII с учетом регистра.
at_hash Хэш токена доступа. Обеспечивает проверку того, что маркер доступа привязан к маркеру удостоверения. Если токен ID выдается со значением access_token в потоке сервера, это утверждение всегда включается. Это утверждение можно использовать в качестве альтернативного механизма для защиты от атак с подделкой межсайтовых запросов, но если вы выполните шаги 1 и 3 , проверять маркер доступа не нужно.
azp client_id авторизованного докладчика. Это утверждение необходимо только в том случае, если сторона, запрашивающая токен идентификатора, не совпадает с аудиторией токена идентификатора. Это может иметь место в Google для гибридных приложений, когда веб-приложение и приложение для Android имеют разные client_id OAuth 2.0, но используют один и тот же проект Google API.
email Электронный адрес пользователя. Это значение может быть не уникальным для этого пользователя и не подходит для использования в качестве первичного ключа. Предоставляется, только если ваша область включает значение области email .
email_verified Истинно, если адрес электронной почты пользователя подтвержден; иначе ложно.
family_name Фамилия(и) или фамилия(и) пользователя. Может предоставляться при наличии заявки на name .
given_name Имя (имена) или имя (имена) пользователя. Может предоставляться при наличии заявки на name .
hd Размещенный домен G Suite пользователя. Предоставляется, только если пользователь принадлежит к размещенному домену.
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, пока пользователь не присутствует в вашем приложении. Чтобы запросить токен обновления, добавьте для параметра access_type значение offline в запросе аутентификации .

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

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

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

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

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

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

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

Параметр необходимые Описание
client_id (Необходимые) Строка идентификатора клиента, полученная из API ConsoleCredentials page, как описано в разделе Получение учетных данных OAuth 2.0 .
nonce (Необходимые) Случайное значение, сгенерированное вашим приложением, которое включает защиту от повторного воспроизведения.
response_type (Необходимые) Если значение равно code , запускает основной поток кода авторизации , требующий POST для конечной точки токена для получения токенов. Если значение равно token id_token или id_token token , запускает неявный поток , требующий использования JavaScript в URI перенаправления для извлечения токенов из идентификатора #fragment URI .
redirect_uri (Необходимые) Определяет, куда отправляется ответ. Значение этого параметра должно точно совпадать с одним из авторизованных значений перенаправления, которые вы установили в API ConsoleCredentials page (включая схему 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 в основном потоке и в идентификаторе #fragment URI в неявном потоке.

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

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

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

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

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

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

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

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

  • consent

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

  • select_account

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

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

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

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

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

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

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

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

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

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

Шаги со 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 позволяет использовать «документ обнаружения», документ JSON, найденный в известном месте, содержащий пары «ключ-значение», которые предоставляют подробную информацию о конфигурации поставщика OpenID Connect, включая URI авторизации. , токен, отзыв, информация о пользователе и конечные точки открытых ключей. Документ 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 ) в своем приложении. Ваше приложение извлекает документ, применяет к ответу правила кэширования, а затем по мере необходимости извлекает из него 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, кэшируя значения из документа обнаружения. Используются стандартные заголовки кэширования HTTP, и их следует соблюдать.

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

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

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

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