Упрощенное связывание с помощью OAuth и Google Sign-In

Обзор

Упрощенное связывание Google Sign-In на основе OAuth добавляет вход Google поверх связывания OAuth . Это обеспечивает удобство привязки для пользователей Google, а также позволяет создавать учетные записи, что позволяет пользователю создать новую учетную запись в вашей службе, используя свою учетную запись Google.

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

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

Рисунок 1 . Связывание учетной записи на телефоне пользователя с помощью Streamlined Linking

Требования для упрощенного связывания

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

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

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

  1. Есть ли у пользователя учетная запись в вашей системе аутентификации? (Пользователь решает, выбирая ДА или НЕТ)
    1. ДА : Использует ли пользователь адрес электронной почты, связанный с его учетной записью Google, для входа на вашу платформу? (Пользователь решает, выбирая ДА или НЕТ)
      1. ДА : Есть ли у пользователя соответствующая учетная запись в вашей системе аутентификации? ( check intent вызывается для подтверждения)
        1. YES : вызывается get intent , и учетная запись связывается, если getintent возвращается успешно.
        2. НЕТ : Создать новую учетную запись? (Пользователь решает, выбирая ДА или НЕТ)
          1. YES : вызывается create intent , и учетная запись связывается, если создание намерения возвращается успешно.
          2. НЕТ : запускается веб-поток OAuth, пользователь направляется в свой браузер, и ему предоставляется возможность установить ссылку с другим адресом электронной почты.
      2. НЕТ : запускается веб-поток OAuth , пользователь направляется в свой браузер, и ему предоставляется возможность установить ссылку с другим адресом электронной почты.
    2. NO : Есть ли у пользователя соответствующая учетная запись в вашей системе аутентификации? ( check intent вызывается для подтверждения)
      1. YES : вызывается get intent , и учетная запись связывается, если getintent возвращается успешно.
      2. NO : вызывается create intent , и учетная запись связывается, если создание намерения возвращается успешно.

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

После того как пользователь дает согласие на доступ к своему профилю 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&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

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

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

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

  • Проверьте и декодируйте утверждение JWT.
  • Убедитесь, что учетная запись 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 в вашей системе аутентификации.

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

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

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

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

{
  "account_found":"true",
}

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

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

{
  "account_found":"false",
}

Обработка автоматического связывания (получение намерения)

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

Если соответствующая учетная запись Google уже присутствует в вашей системе аутентификации, конечная точка обмена токенами возвращает токен для пользователя. Если учетная запись Google не соответствует существующему пользователю, конечная точка обмена токенами возвращает ошибку 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&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

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

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

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

  • Проверьте и декодируйте утверждение JWT.
  • Убедитесь, что учетная запись 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 в вашей системе аутентификации.

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

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

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

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

  "refresh_token": "REFRESH_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

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

Handle account creation via Google Sign-In (create intent)

When a user needs to create an account on your service, Google makes a request to your token exchange endpoint that specifies intent=create.

The request has the following form:

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&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

Your token exchange endpoint must able to handle the following parameters:

Token endpoint parameters
intent For these requests, the value of this parameter is create.
grant_type The type of token being exchanged. For these requests, this parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address.
client_id The client ID you assigned to Google.
client_secret The client secret you assigned to Google.

The JWT within the assertion parameter contains the user's Google Account ID, name, and email address, which you can use to create a new account on your service.

To respond to the create intent requests, your token exchange endpoint must perform the following steps:

  • Validate and decode the JWT assertion.
  • Validate user information and create new account.
Проверить и декодировать утверждение 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, однако право собственности на стороннюю учетную запись электронной почты с тех пор могло измениться.

Validate user information and create new account

Check whether either of the following conditions are true:

  • The Google Account ID, found in the assertion's sub field, is in your user database.
  • The email address in the assertion matches a user in your user database.

If either condition is true, prompt the user to link their existing account with their Google Account. To do so, respond to the request with an HTTP 401 error that specifies error=linking_error and gives the user's email address as the login_hint. The following is a sample response:

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

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

When Google receives a 401 error response with linking_error, Google sends the user to your authorization endpoint with login_hint as a parameter. The user completes account linking using the OAuth linking flow in their browser.

If neither condition is true, create a new user account with the information provided in the JWT. New accounts don't typically have a password set. It's recommended that you add Google Sign-In to other platforms to enable users to log in with Google across the surfaces of your application. Alternatively, you can email the user a link that starts your password recovery flow to allow the user to set a password to sign in on other platforms.

When the creation is completed, issue an access token and refresh token and return the values in a JSON object in the body of your HTTPS response, like in the following example:

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

  "refresh_token": "REFRESH_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

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

Вам потребуется указать свой идентификатор клиента Google API в процессе регистрации привязки учетной записи.

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

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

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

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

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

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

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

Вы можете проверить свою реализацию с помощью учетной записи Google Linking Демо инструмент.

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

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