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

Обзор

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

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

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

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

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

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

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

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

检查现有用户账号(检查 intent)

在用户同意访问其 Google 个人资料后,Google 会发送 请求,其中包含 Google 用户身份的已签名断言。通过 断言包含的信息包括用户的 Google 账号 ID、 姓名和电子邮件地址为您的 Google Cloud 控制台配置的令牌交换端点 项目处理该请求。

如果您的身份验证中已有相应的 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 Web 令牌 (JWT),提供 Google 用户身份。JWT 包含的信息包括用户 Google 账号 ID、姓名和电子邮件地址。
client_id 您分配给 Google 的客户 ID。
client_secret 您分配给 Google 的客户端密钥。

如需响应 check intent 请求,您的令牌交换端点必须执行以下步骤:

  • 验证和解码 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_verified 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 账号 ID(可在断言的 sub 字段中找到)位于您的用户中 数据库。
  • 断言中的电子邮件地址与用户数据库中的用户匹配。

如果满足上述任一条件,则表明用户已注册。在这种情况下 返回如下所示的响应:

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

{
  "account_found":"true",
}

如果 Google 账号 ID 和 断言与您的数据库中的用户匹配,该用户尚未注册。在 在这种情况下,您的令牌交换端点需要返回 HTTP 404 错误 指定 "account_found": "false",如以下示例所示:

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

{
  "account_found":"false",
}

处理自动链接(获取 intent)

在用户同意访问其 Google 个人资料后,Google 会发送 请求,其中包含 Google 用户身份的已签名断言。通过 断言包含的信息包括用户的 Google 账号 ID、 姓名和电子邮件地址为您的 Google Cloud 控制台配置的令牌交换端点 项目处理该请求。

如果您的身份验证中已有相应的 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 Web 令牌 (JWT),提供 Google 用户身份。JWT 包含的信息包括用户 Google 账号 ID、姓名和电子邮件地址。
scope 可选:您已将 Google 配置为向其请求访问权限的任何范围 用户。
client_id 您分配给 Google 的客户 ID。
client_secret 您分配给 Google 的客户端密钥。

如需响应 get intent 请求,您的令牌交换端点必须执行以下步骤:

  • 验证和解码 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_verified 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 账号 ID(可在断言的 sub 字段中找到)位于您的用户中 数据库。
  • 断言中的电子邮件地址与用户数据库中的用户匹配。

如果找到了用户的账号,请发出访问令牌,并在 HTTPS 响应正文的 JSON 对象中返回相应值,如以下示例所示:

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

  "refresh_token": "REFRESH_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

在某些情况下,基于 ID 令牌的账号关联可能会失败。如果 因为任何原因,您的令牌交换端点都需要以 HTTP 响应 指定 error=linking_error 的 401 错误,如以下示例所示:

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

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

当 Google 收到包含 linking_error 的 401 错误响应时,会发送 使用 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.
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_verified 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.

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. Откройте страницу «Учетные данные» консоли Google API .
  2. Создайте или выберите проект Google API.

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

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

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

В инструменте выполните следующие действия:

  1. Нажмите конфигурации» , чтобы открыть окно «Конфигурация OAuth 2.0».
  2. В поле «Поток OAuth» выберите «Клиентская сторона» .
  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. Подтвердите, что вы перенаправлены на вашу платформу.