Упрощенное связывание с помощью 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 , и учетная запись связывается, если создание намерения возвращается успешно.

Check for an existing user account (check intent)

After the user gives consent to access their Google profile, Google sends a request that contains a signed assertion of the Google user's identity. The assertion contains information that includes the user's Google Account ID, name, and email address. The token exchange endpoint configured for your project handles that request.

If the corresponding Google account is already present in your authentication system, your token exchange endpoint responds with account_found=true. If the Google account doesn't match an existing user, your token exchange endpoint returns an HTTP 404 Not Found error with account_found=false.

The request has the following form:

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

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

Token endpoint parameters
intent For these requests, the value of this parameter is check.
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.

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

  • Validate and decode the JWT assertion.
  • Check if the Google account is already present in your authentication system.
Validate and decode the JWT assertion

You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.

When decoded, the JWT assertion looks like the following example:

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

In addition to verifying the token's signature, verify that the assertion's issuer (iss field) is https://accounts.google.com, that the audience (aud field) is your assigned client ID, and that the token has not expired (exp field).

Using the email, email_verified and hd fields you can determine if Google hosts and is authoritative for an email address. In cases where Google is authoritative the user is currently known to be the legitimate account owner and you may skip password or other challenges methods. Otherwise, these methods can be used to verify the account prior to linking.

Cases where Google is authoritative:

  • email has a @gmail.com suffix, this is a Gmail account.
  • email_verified is true and hd is set, this is a G Suite account.

Users may register for Google Accounts without using Gmail or G Suite. When email does not contain a @gmail.com suffix and hd is absent Google is not authoritative and password or other challenge methods are recommended to verify the user. email_verfied can also be true as Google initially verified the user when the Google account was created, however ownership of the third party email account may have since changed.

Check if the Google account is already present in your authentication system

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, the user has already signed up. In that case, return a response like the following:

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

{
  "account_found":"true",
}

If neither the Google Account ID nor the email address specified in the assertion matches a user in your database, the user hasn't signed up yet. In this case, your token exchange endpoint needs to reply with a HTTP 404 error that specifies "account_found": "false", as in the following example:

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 уже присутствует в вашей системе аутентификации.
Validate and decode the JWT assertion

You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.

When decoded, the JWT assertion looks like the following example:

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

In addition to verifying the token's signature, verify that the assertion's issuer (iss field) is https://accounts.google.com, that the audience (aud field) is your assigned client ID, and that the token has not expired (exp field).

Using the email, email_verified and hd fields you can determine if Google hosts and is authoritative for an email address. In cases where Google is authoritative the user is currently known to be the legitimate account owner and you may skip password or other challenges methods. Otherwise, these methods can be used to verify the account prior to linking.

Cases where Google is authoritative:

  • email has a @gmail.com suffix, this is a Gmail account.
  • email_verified is true and hd is set, this is a G Suite account.

Users may register for Google Accounts without using Gmail or G Suite. When email does not contain a @gmail.com suffix and hd is absent Google is not authoritative and password or other challenge methods are recommended to verify the user. email_verfied can also be true as Google initially verified the user when the Google account was created, however ownership of the third party email account may have since changed.

Проверьте, присутствует ли учетная запись 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 в своем браузере.

Управление созданием учетной записи с помощью входа в систему Google (создание намерения)

Когда пользователю необходимо создать учетную запись в вашем сервисе, 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&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

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

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

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

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

  • Проверьте и декодируйте утверждение JWT.
  • Проверьте информацию о пользователе и создайте новую учетную запись.
Validate and decode the JWT assertion

You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.

When decoded, the JWT assertion looks like the following example:

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

In addition to verifying the token's signature, verify that the assertion's issuer (iss field) is https://accounts.google.com, that the audience (aud field) is your assigned client ID, and that the token has not expired (exp field).

Using the email, email_verified and hd fields you can determine if Google hosts and is authoritative for an email address. In cases where Google is authoritative the user is currently known to be the legitimate account owner and you may skip password or other challenges methods. Otherwise, these methods can be used to verify the account prior to linking.

Cases where Google is authoritative:

  • email has a @gmail.com suffix, this is a Gmail account.
  • email_verified is true and hd is set, this is a G Suite account.

Users may register for Google Accounts without using Gmail or G Suite. When email does not contain a @gmail.com suffix and hd is absent Google is not authoritative and password or other challenge methods are recommended to verify the user. email_verfied can also be true as Google initially verified the user when the Google account was created, however ownership of the third party email account may have since changed.

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

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

  • Идентификатор учетной записи 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
}

Получите свой идентификатор клиента 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. Подтвердите, что вы перенаправлены на свою платформу.