Vinculación optimizada con OAuth y Acceso con Google

Descripción general

La vinculación optimizada del Acceso con Google basado en OAuth agrega el Acceso con Google por encima de Vinculación de OAuth. Esto proporciona una experiencia de vinculación fluida para a los usuarios de Google y, además, habilita la creación de cuentas, que les permite crear una cuenta nueva en tu servicio con su Cuenta de Google.

Para vincular las cuentas con OAuth y el Acceso con Google, sigue estas indicaciones generales pasos:

  1. En primer lugar, solicita al usuario que dé su consentimiento para acceder a su perfil de Google.
  2. Usa la información de su perfil para comprobar si existe la cuenta de usuario.
  3. Para los usuarios existentes, vincula las cuentas.
  4. Si no encuentras una coincidencia para el usuario de Google en tu sistema de autenticación, validar el token de ID que se recibió de Google. Luego, puedes crear un usuario basado en en la información de perfil que se encuentra en el token de ID.
En esta figura, se muestran los pasos para que un usuario vincule su Cuenta de Google con el flujo de vinculación optimizado. La primera captura de pantalla muestra cómo un usuario puede seleccionar tu app para vincularla. La segunda captura de pantalla le permite al usuario confirmar si tiene una cuenta existente en tu servicio. La tercera captura de pantalla le permite al usuario seleccionar la Cuenta de Google con la que desea vincularse. La cuarta captura de pantalla muestra la confirmación para vincular su Cuenta de Google con tu app. En la quinta captura de pantalla, se muestra una cuenta de usuario vinculada correctamente en la app de Google.

Figura 1. Vinculación de cuentas en el teléfono de un usuario con la vinculación optimizada

Requisitos para una vinculación optimizada

Implementa tu servidor de OAuth

El extremo de intercambio de tokens debe admitir los intents check, create y get. A continuación, se muestran los pasos completados a través del flujo de vinculación de cuentas y se indica cuándo se llama a los diferentes intents:

  1. ¿El usuario tiene una cuenta en tu sistema de autenticación? (El usuario decide si selecciona SÍ o NO)
    1. SÍ: ¿El usuario usa el correo electrónico asociado a su Cuenta de Google para acceder a tu plataforma? (El usuario decide si selecciona SÍ o NO)
      1. SÍ: ¿El usuario tiene una cuenta que coincida en tu sistema de autenticación? (Se llama a check intent para confirmar).
        1. SÍ : Se llama a get intent y se vincula la cuenta si se muestra correctamente el intent GET.
        2. NO, ¿crear una cuenta nueva? (El usuario decide si selecciona SÍ o NO)
          1. SÍ : Si se muestra correctamente el intent de creación, se llama a create intent y se vincula la cuenta.
          2. NO : Se activa el flujo de OAuth web, se dirige al usuario a su navegador y el usuario tiene la opción de vincularse con un correo electrónico diferente.
      2. NO : Se activa el flujo de OAuth web, se dirige al usuario a su navegador y se le ofrece la opción de vincular con un correo electrónico diferente.
    2. NO: ¿El usuario tiene una cuenta que coincida en tu sistema de autenticación? (Se llama a check intent para confirmar).
      1. SÍ : Se llama a get intent y se vincula la cuenta si se muestra correctamente el intent GET.
      2. NO : Se llama a create intent y se vincula la cuenta si se muestra correctamente el intent de creación.

检查现有用户账号(检查 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 账号。
Valida y decodifica la aserción de JWT

Puedes validar y decodificar la aserción de JWT con un Biblioteca de decodificación JWT para tu lenguaje. Usa las claves públicas de Google, disponibles en JWK o PEM para verificar la firma del token.

Cuando se decodifica, la aserción de JWT luce como el siguiente ejemplo:

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

Además de verificar la firma del token, comprueba que el token de la aserción entidad emisora (campo iss) es https://accounts.google.com, que el público (campo aud) es tu ID de cliente asignado y que el token no haya vencido. (Campo exp).

Usa los campos email, email_verified y hd para determinar si Google aloja una dirección de correo electrónico y tiene la autoridad para hacerlo. En los casos en que Google sea autorizado, se sabe que el usuario actualmente es el propietario legítimo de la cuenta y puedes omitir la contraseña y otros métodos de verificación de identidad. De lo contrario, estos métodos se puede usar para verificar la cuenta antes de realizar la vinculación.

Casos en los que Google es confiable:

  • email tiene el sufijo @gmail.com; esta es una cuenta de Gmail.
  • email_verified es verdadero y hd está configurado. Esta es una cuenta de G Suite.

Los usuarios pueden registrarse en Cuentas de Google sin usar Gmail ni G Suite. Cuándo email no contiene un sufijo @gmail.com ni hd, ni tampoco se recomienda verificar con métodos de verificación, tanto confiables como con contraseñas del usuario. email_verified también puede ser verdadero, ya que Google verificó inicialmente el usuario cuando se creó la cuenta de Google, sin embargo, la propiedad del tercero de correo electrónico puede haber cambiado desde entonces.

检查您的身份验证系统中是否已存在该 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 账号。
Valida y decodifica la aserción de JWT

Puedes validar y decodificar la aserción de JWT con un Biblioteca de decodificación JWT para tu lenguaje. Usa las claves públicas de Google, disponibles en JWK o PEM para verificar la firma del token.

Cuando se decodifica, la aserción de JWT luce como el siguiente ejemplo:

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

Además de verificar la firma del token, comprueba que el token de la aserción entidad emisora (campo iss) es https://accounts.google.com, que el público (campo aud) es tu ID de cliente asignado y que el token no haya vencido. (Campo exp).

Usa los campos email, email_verified y hd para determinar si Google aloja una dirección de correo electrónico y tiene la autoridad para hacerlo. En los casos en que Google sea autorizado, se sabe que el usuario actualmente es el propietario legítimo de la cuenta y puedes omitir la contraseña y otros métodos de verificación de identidad. De lo contrario, estos métodos se puede usar para verificar la cuenta antes de realizar la vinculación.

Casos en los que Google es confiable:

  • email tiene el sufijo @gmail.com; esta es una cuenta de Gmail.
  • email_verified es verdadero y hd está configurado. Esta es una cuenta de G Suite.

Los usuarios pueden registrarse en Cuentas de Google sin usar Gmail ni G Suite. Cuándo email no contiene un sufijo @gmail.com ni hd, ni tampoco se recomienda verificar con métodos de verificación, tanto confiables como con contraseñas del usuario. email_verified también puede ser verdadero, ya que Google verificó inicialmente el usuario cuando se creó la cuenta de Google, sin embargo, la propiedad del tercero de correo electrónico puede haber cambiado desde entonces.

检查您的身份验证系统中是否已存在该 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 关联流程完成账号关联。

通过 Google 登录功能处理账号创建(创建 intent)

当用户需要在您的服务中创建账号时,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 Web 令牌 (JWT),提供 Google 用户身份。JWT 包含的信息包括用户 Google 账号 ID、姓名和电子邮件地址。
client_id 您分配给 Google 的客户 ID。
client_secret 您分配给 Google 的客户端密钥。

assertion 参数中的 JWT 包含用户的 Google 账号 ID。 姓名和电子邮件地址,可用于在 Gmail 中创建新账号 服务。

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

  • 验证和解码 JWT 断言。
  • 验证用户信息并创建新账号。
Valida y decodifica la aserción de JWT

Puedes validar y decodificar la aserción de JWT con un Biblioteca de decodificación JWT para tu lenguaje. Usa las claves públicas de Google, disponibles en JWK o PEM para verificar la firma del token.

Cuando se decodifica, la aserción de JWT luce como el siguiente ejemplo:

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

Además de verificar la firma del token, comprueba que el token de la aserción entidad emisora (campo iss) es https://accounts.google.com, que el público (campo aud) es tu ID de cliente asignado y que el token no haya vencido. (Campo exp).

Usa los campos email, email_verified y hd para determinar si Google aloja una dirección de correo electrónico y tiene la autoridad para hacerlo. En los casos en que Google sea autorizado, se sabe que el usuario actualmente es el propietario legítimo de la cuenta y puedes omitir la contraseña y otros métodos de verificación de identidad. De lo contrario, estos métodos se puede usar para verificar la cuenta antes de realizar la vinculación.

Casos en los que Google es confiable:

  • email tiene el sufijo @gmail.com; esta es una cuenta de Gmail.
  • email_verified es verdadero y hd está configurado. Esta es una cuenta de G Suite.

Los usuarios pueden registrarse en Cuentas de Google sin usar Gmail ni G Suite. Cuándo email no contiene un sufijo @gmail.com ni hd, ni tampoco se recomienda verificar con métodos de verificación, tanto confiables como con contraseñas del usuario. email_verified también puede ser verdadero, ya que Google verificó inicialmente el usuario cuando se creó la cuenta de Google, sin embargo, la propiedad del tercero de correo electrónico puede haber cambiado desde entonces.

验证用户信息并创建新账号

请检查以下任一条件是否成立:

  • Google 账号 ID(可在断言的 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 收到包含 linking_error 的 401 错误响应时,会发送 使用 login_hint 作为参数将用户发送到您的授权端点。通过 用户在浏览器中使用 OAuth 关联流程完成账号关联。

如果以上两个条件都不满足,请使用相应信息创建一个新的用户账号 。新账号通常不会设置密码。时间是 建议您将 Google 登录功能添加到其他平台,以便用户 使用 Google 账号登录。或者 可以通过电子邮件向用户发送链接,启动密码恢复流程,以允许 用户设置密码,以便在其他平台上登录。

创建完成后,发出一个访问令牌 和刷新令牌 并在 HTTPS 响应的正文,如以下示例所示:

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

  "refresh_token": "REFRESH_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

Obtén tu ID de cliente de la API de Google

Tendrá que proporcionar su ID de cliente de la API de Google durante el proceso de registro de la vinculación de cuentas.

Para obtener tu ID de cliente de API con el proyecto que creaste mientras completaste los pasos de la Vinculación con OAuth. Para ello, completa los siguientes pasos:

  1. Abre la página Credenciales de la Consola de APIs de Google.
  2. Crea o selecciona un proyecto de las APIs de Google.

    Si tu proyecto no tiene un ID de cliente para el tipo de aplicación web, haz clic en Crear credenciales > ID de cliente de OAuth para crear uno. Asegúrate de incluir el dominio de tu sitio en el cuadro Orígenes autorizados de JavaScript. Cuando realizas para pruebas o desarrollo locales, debes agregar http://localhost y http://localhost:<port_number> al campo Orígenes autorizados de JavaScript.

Cómo validar la implementación

您可以通过使用验证实现的OAuth 2.0游乐场工具。

在工具中,执行以下步骤:

  1. 单击配置打开的OAuth 2.0配置窗口。
  2. OAuth流场中,选择客户端
  3. OAuth端点字段中,选择自定义
  4. 在相应字段中指定您的 OAuth 2.0 端点和您分配给 Google 的客户端 ID。
  5. 步骤1部分,不要选择任何谷歌范围。相反,将此字段留空或键入对您的服务器有效的范围(如果不使用 OAuth 范围,则输入任意字符串)。当您完成后,单击授权的API。
  6. 步骤2步骤3段,完成OAuth 2.0流程和验证每个步骤按预期工作。

您可以通过验证您的实现谷歌帐户链接演示工具。

在工具中,执行以下步骤:

  1. 点击登录在与谷歌按钮。
  2. 选择您要关联的帐户。
  3. 输入服务标识。
  4. (可选)输入您将请求访问的一个或多个范围。
  5. 单击开始演示
  6. 出现提示时,确认您可以同意并拒绝链接请求。
  7. 确认您被重定向到您的平台。