Оптимизированное связывание с помощью OAuth и входа в Google

Обзор

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

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

  1. Сначала попросите пользователя дать согласие на доступ к своему профилю Google.
  2. Используйте информацию в их профиле, чтобы проверить, существует ли учетная запись пользователя.
  3. Для существующих пользователей свяжите учетные записи.
  4. Если вы не можете найти совпадение с пользователем Google в своей системе аутентификации, проверьте полученный от Google токен идентификатора. Затем вы можете создать пользователя на основе информации профиля, содержащейся в токене идентификатора.

Рисунок 3 . Связывание аккаунтов на телефоне пользователя с помощью оптимизированного связывания

Учетные записи связаны с использованием неявного отраслевого стандарта OAuth 2.0 и потоков кода авторизации . Ваша служба должна поддерживать конечные точки авторизации и обмена токенами, совместимые с OAuth 2.0. Кроме того, ваша конечная точка обмена токенами должна поддерживать утверждения JSON Web Token (JWT) и реализовывать намерения check , create и get .

Получите свой идентификатор клиента и секрет Google API

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

  1. Откройте страницу учетных данных консоли Google API .
  2. Создайте или выберите проект API Google.

    Если в вашем проекте нет идентификатора клиента для типа веб-приложения, щелкните « Создать учетные данные»> «Идентификатор клиента OAuth», чтобы создать его. Обязательно укажите домен вашего сайта в поле « Авторизованные источники JavaScript» . При выполнении локальных тестов или разработки необходимо добавить как http://localhost и http://localhost:<port_number> в поле « Авторизованные источники JavaScript» .

Внедрите свой сервер OAuth

Проверить наличие существующей учетной записи пользователя

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

Если соответствующая учетная запись Google уже присутствует в вашей системе аутентификации, ваша конечная точка обмена токенами отвечает с помощью account_found=true . Если учетная запись Google не соответствует существующему пользователю, ваша конечная точка обмена токенами возвращает ошибку HTTP 404 Not Found с account_found=false .

Запрос имеет следующую форму:

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

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=check&assertion=JWT&scope=SCOPES

Конечная точка обмена токенами должна поддерживать следующие параметры:

Параметры конечной точки токена
intent Для этих запросов значение этого параметра check .
grant_type Тип обмениваемого токена. Для этих запросов этот параметр имеет значение urn:ietf:params:oauth:grant-type:jwt-bearer .
assertion Веб-токен JSON (JWT), который обеспечивает подписанное подтверждение личности пользователя Google. JWT содержит информацию, которая включает идентификатор учетной записи Google, имя и адрес электронной почты пользователя.

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

Проверить и декодировать утверждение JWT

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

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

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

Помимо проверки подписи токена, убедитесь, что эмитент утверждения (поле iss ) - https://accounts.google.com , аудитория (поле aud ) - это ваш назначенный идентификатор клиента и что срок действия токена не истек ( exp поле).

Используя поля email , email_verified и hd вы можете определить, является ли Google хостом и является ли он авторитетным для адреса электронной почты. В случаях, когда Google является авторитетным, пользователь в настоящее время известен как законный владелец учетной записи, и вы можете пропустить пароль или другие методы проверки. В противном случае эти методы можно использовать для проверки учетной записи перед установкой связи.

Случаи, когда Google является авторитетным:

  • email имеет суффикс @gmail.com , это учетная запись Gmail.
  • email_verified имеет значение true и установлен hd , это учетная запись G Suite.

Пользователи могут регистрировать учетные записи Google без использования Gmail или G Suite. Если email не содержит суффикса @gmail.com и hd отсутствует, Google не является официальным, и для проверки пользователя рекомендуется использовать пароль или другие методы проверки. email_verfied также может иметь значение true, поскольку Google изначально проверил пользователя при создании учетной записи Google, однако право собственности на стороннюю учетную запись электронной почты с тех пор могло измениться.

Убедитесь, что учетная запись Google уже присутствует в вашей системе аутентификации.

Проверьте, выполняется ли одно из следующих условий:

  • Идентификатор аккаунта Google, найденный в утверждении в sub области, находится в базе данных пользователя.
  • Адрес электронной почты в утверждении соответствует пользователю в вашей базе данных пользователей.

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

HTTP/1.1 200 Success
Content-Type: application/json;charset=UTF-8

{
  "account_found":"true",
}

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

Если ни идентификатор учетной записи Google, ни адрес электронной почты, указанный в утверждении, не соответствует пользователю в вашей базе данных, пользователь еще не зарегистрировался. В этом случае конечная точка обмена токенами должна ответить с ошибкой HTTP 404, в которой указано "account_found": "false" , как в следующем примере:

HTTP/1.1 404 Not found
Content-Type: application/json;charset=UTF-8

{
  "account_found":"false",
}
Когда Google получает ответ об ошибке 404 с ошибкой "account_found": "false" , Google отображает диалоговое окно для пользователя, чтобы запросить согласие на создание новой учетной записи и доступ к желаемым областям. После того, как Google получает согласие пользователя, Google вызывает вашу конечную точку обмена токенами со значением параметра intent установленным для create и включает в запрос токен идентификатора, который содержит информацию профиля пользователя.

Обработка автоматического связывания

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

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

Запрос имеет следующую форму:

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

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=get&assertion=JWT&scope=SCOPES

Конечная точка обмена токенами должна поддерживать следующие параметры:

Параметры конечной точки токена
intent Для этих запросов значение этого параметра равно get .
grant_type Тип обмениваемого токена. Для этих запросов этот параметр имеет значение urn:ietf:params:oauth:grant-type:jwt-bearer .
assertion Веб-токен JSON (JWT), который обеспечивает подписанное подтверждение личности пользователя Google. JWT содержит информацию, которая включает идентификатор учетной записи Google, имя и адрес электронной почты пользователя.
scope Необязательно: любые области, которые вы настроили Google для запроса у пользователей.

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

Проверить и декодировать утверждение JWT

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

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

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

Помимо проверки подписи токена, убедитесь, что эмитент утверждения (поле iss ) - https://accounts.google.com , аудитория (поле aud ) - это ваш назначенный идентификатор клиента и что срок действия токена не истек ( exp поле).

Используя поля email , email_verified и hd вы можете определить, является ли Google хостом и является ли он авторитетным для адреса электронной почты. В случаях, когда Google является авторитетным, пользователь в настоящее время известен как законный владелец учетной записи, и вы можете пропустить пароль или другие методы проверки. В противном случае эти методы можно использовать для проверки учетной записи перед установкой связи.

Случаи, когда Google является авторитетным:

  • email имеет суффикс @gmail.com , это учетная запись Gmail.
  • email_verified имеет значение true и установлен hd , это учетная запись G Suite.

Пользователи могут регистрировать учетные записи Google без использования Gmail или G Suite. Если email не содержит суффикса @gmail.com и hd отсутствует, Google не является официальным, и для проверки пользователя рекомендуется использовать пароль или другие методы проверки. email_verfied также может иметь значение true, поскольку Google изначально проверил пользователя при создании учетной записи Google, однако право собственности на стороннюю учетную запись электронной почты с тех пор могло измениться.

Убедитесь, что учетная запись Google уже присутствует в вашей системе аутентификации.

Проверьте, выполняется ли одно из следующих условий:

  • Идентификатор аккаунта Google, найденный в утверждении в sub области, находится в базе данных пользователя.
  • Адрес электронной почты в утверждении соответствует пользователю в вашей базе данных пользователей.

В некоторых случаях привязка учетной записи на основе идентификатора может не работать для пользователя. Если это произойдет по какой-либо причине, ваша конечная точка обмена токенами должна ответить с ошибкой HTTP 401, которая указывает error=linking_error , как показано в следующем примере:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}
Когда Google получает ответ об ошибке 401 с linking_error , Google вызывает вашу конечную точку обмена linking_error , linking_error в запросе следующее:

  • Набор параметров intent для create
  • JWT с токеном идентификатора и информацией профиля пользователя

Создание учетной записи через Google Sign-In

Когда пользователю необходимо создать учетную запись в вашем сервисе, Google делает запрос к вашей конечной точке обмена токенами, в которой указано intent=create .

Запрос имеет следующую форму:

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

response_type=token&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=SCOPES&intent=create&assertion=JWT[&NEW_ACCOUNT_INFO]

Конечная точка обмена токенами должна поддерживать следующие параметры:

Параметры конечной точки токена
intent Для этих запросов значение этого параметра равно create .
grant_type Тип обмениваемого токена. Для этих запросов этот параметр имеет значение urn:ietf:params:oauth:grant-type:jwt-bearer .
assertion Веб-токен JSON (JWT), который обеспечивает подписанное подтверждение личности пользователя Google. JWT содержит информацию, которая включает идентификатор учетной записи Google, имя и адрес электронной почты пользователя.

JWT в параметре assertion содержит идентификатор учетной записи Google пользователя, имя и адрес электронной почты, которые вы можете использовать для создания новой учетной записи в своей службе.

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

Проверить и декодировать утверждение JWT

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

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

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

Помимо проверки подписи токена, убедитесь, что эмитент утверждения (поле iss ) - https://accounts.google.com , аудитория (поле aud ) - это ваш назначенный идентификатор клиента и что срок действия токена не истек ( exp поле).

Используя поля email , email_verified и hd вы можете определить, является ли Google хостом и является ли он авторитетным для адреса электронной почты. В случаях, когда Google является авторитетным, пользователь в настоящее время известен как законный владелец учетной записи, и вы можете пропустить пароль или другие методы проверки. В противном случае эти методы можно использовать для проверки учетной записи перед установкой связи.

Случаи, когда Google является авторитетным:

  • email имеет суффикс @gmail.com , это учетная запись Gmail.
  • email_verified имеет значение true и установлен hd , это учетная запись G Suite.

Пользователи могут регистрировать учетные записи Google без использования Gmail или G Suite. Если email не содержит суффикса @gmail.com и hd отсутствует, Google не является официальным, и для проверки пользователя рекомендуется использовать пароль или другие методы проверки. email_verfied также может иметь значение true, поскольку Google изначально проверил пользователя при создании учетной записи Google, однако право собственности на стороннюю учетную запись электронной почты с тех пор могло измениться.

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

Проверьте, выполняется ли одно из следующих условий:

  • Идентификатор аккаунта Google, найденный в утверждении в sub области, находится в базе данных пользователя.
  • Адрес электронной почты в утверждении соответствует пользователю в вашей базе данных пользователей.

Если выполняется одно из условий, предложите пользователю связать существующую учетную запись со своей учетной записью Google. Для этого ответьте на запрос с ошибкой HTTP 401, которая указывает error=linking_error и дает адрес электронной почты пользователя как login_hint . Ниже приводится пример ответа:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

Когда Google получает ответ об ошибке 401 с linking_error , Google отправляет пользователя в конечную точку авторизации с параметром login_hint . Пользователь завершает привязку учетной записи, используя процесс связывания OAuth в своем браузере.

Если ни одно из условий не выполняется, создайте новую учетную запись пользователя с информацией, предоставленной в JWT. Для новых учетных записей обычно не устанавливается пароль. Рекомендуется добавить Google Sign-In на другие платформы, чтобы пользователи могли входить в систему с помощью Google на всех поверхностях вашего приложения. Кроме того, вы можете отправить пользователю по электронной почте ссылку, которая запускает процесс восстановления пароля, чтобы пользователь мог установить пароль для входа на других платформах.

По завершении создания выдайте токен доступа и обновите токен и верните значения в объекте JSON в теле ответа HTTPS, как в следующем примере:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "refresh_token": "REFRESH_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

Проверка вашей реализации

Вы можете проверить свою реализацию с помощью инструмента OAuth 2.0 Playground .

В инструменте проделайте следующие шаги:

  1. Щелкните конфигурации чтобы открыть окно конфигурации OAuth 2.0.
  2. В поле потока OAuth выберите Client-side .
  3. В поле Конечные точки OAuth выберите Пользовательский .
  4. Укажите конечную точку OAuth 2.0 и идентификатор клиента, присвоенный Google, в соответствующих полях.
  5. В разделе Шаг 1 не выбирайте области Google. Вместо этого оставьте это поле пустым или введите область действия, действительную для вашего сервера (или произвольную строку, если вы не используете области действия OAuth). Когда вы закончите, нажмите « Авторизовать API» .
  6. В разделах Шаг 2 и Шаг 3 просмотрите поток OAuth 2.0 и убедитесь, что каждый шаг работает должным образом.

Вы можете проверить свою реализацию с помощью инструмента демонстрации связывания аккаунтов Google .

В инструменте проделайте следующие шаги:

  1. Нажмите кнопку Войти через Google .
  2. Выберите учетную запись, которую вы хотите связать.
  3. Введите идентификатор службы.
  4. При желании введите одну или несколько областей, для которых вы запрашиваете доступ.
  5. Щелкните « Начать демонстрацию» .
  6. При появлении запроса подтвердите, что вы можете согласиться, и отклоните запрос на установление связи.
  7. Подтвердите, что вы перенаправлены на свою платформу.