Vinculación de cuentas con OAuth (Dialogflow)

El tipo de vinculación OAuth es compatible con dos flujos de OAuth 2.0 estándar de la industria: el flujo de código implícito y el de autorización.

En el flujo de código implícito, Google abre tu extremo de autorización en el navegador del usuario. Después de acceder correctamente, devuelves un token de acceso de larga duración a Google. Este token de acceso ahora se incluye en cada solicitud que envía el Asistente a tu acción.

En el flujo de código de autorización, necesitas dos extremos:

  • El extremo authorization, que se encarga de presentar la IU de acceso a los usuarios que aún no accedieron y de registrar el consentimiento para el acceso solicitado en forma de un código de autorización de corta duración.
  • El extremo de intercambio de tokens, que es responsable de dos tipos de intercambios:
    1. Intercambia un código de autorización por un token de actualización de larga duración y un token de acceso de corta duración. Este intercambio se produce cuando el usuario pasa por el flujo de vinculación de cuentas.
    2. Intercambia un token de actualización de larga duración por un token de acceso de corta duración. Este intercambio ocurre cuando Google necesita un token de acceso nuevo porque el que había vencido.

Si bien el flujo de código implícito es más fácil de implementar, Google recomienda que los tokens de acceso emitidos con el flujo implícito nunca venzan, porque el vencimiento del token con el flujo implícito obliga al usuario a vincular su cuenta nuevamente. Si necesitas el vencimiento del token por razones de seguridad, debes considerar usar el flujo de código de Auth.

Implementa la vinculación de cuentas mediante OAuth

Configura el proyecto

Si deseas configurar tu proyecto para que use la vinculación de cuentas de OAuth, sigue estos pasos:

  1. Abre la Consola de Actions y selecciona el proyecto que deseas usar.
  2. Haz clic en la pestaña Desarrollo y elige Vinculación de cuentas.
  3. Habilita el interruptor que se encuentra junto a Vinculación de cuentas.
  4. En la sección Creación de cuenta, selecciona No, solo deseo permitir la creación de cuentas en mi sitio web.

  5. En Tipo de vinculación, selecciona Implícito y OAuth.

  6. En Información del cliente (Client information), haz lo siguiente:

    • Asigna un valor al ID de cliente emitido por tus acciones a Google para identificar las solicitudes que provienen de Google.
    • Inserta las URL para tus extremos de autorización y de intercambio de tokens.
  1. Haz clic en Guardar.

Implementa tu servidor OAuth

Para admitir el flujo implícito de OAuth 2.0, tu servicio pone a disposición un extremo de autorización mediante HTTPS. Este extremo es responsable de autenticar y obtener el consentimiento de los usuarios para el acceso a los datos. El extremo de autorización presenta una IU de acceso a los usuarios que aún no accedieron y registra su consentimiento para el acceso solicitado.

Cuando tu Acción necesita llamar a una de las APIs autorizadas de tu servicio, Google usa este extremo a fin de obtener permiso de los usuarios para llamar a estas APIs en su nombre.

Una sesión típica de flujo implícito de OAuth 2.0 que inicia Google tiene el siguiente flujo:

  1. Google abrirá tu extremo de autorización en el navegador del usuario. El usuario accede si aún no lo ha hecho y le otorga permiso a Google para acceder a sus datos con tu API si aún no lo ha hecho.
  2. Tu servicio crea un token de acceso y lo muestra a Google. Para ello, redirecciona el navegador del usuario a Google con el token de acceso adjunto a la solicitud.
  3. Google llama a las APIs de tu servicio y adjunta el token de acceso a cada solicitud. El servicio verifica que el token de acceso otorgue a Google autorización para acceder a la API y, luego, completa la llamada a la API.

Cómo controlar solicitudes de autorización

Cuando tu Acción necesita realizar una vinculación de cuentas a través de un flujo implícito de OAuth2, Google envía al usuario a tu extremo de autorización con una solicitud que incluye los siguientes parámetros:

Parámetros del extremo de autorización
client_id El ID de cliente que asignaste a Google.
redirect_uri La URL a la que envías la respuesta a esta solicitud.
state Es un valor de contabilidad que se pasa a Google sin cambios en el URI de redireccionamiento.
response_type Es el tipo de valor que se muestra en la respuesta. Para el flujo implícito de OAuth 2.0, el tipo de respuesta siempre es token.

Por ejemplo, si tu extremo de autorización está disponible en https://myservice.example.com/auth, una solicitud podría verse de la siguiente manera:

GET https://myservice.example.com/auth?client_id=GOOGLE_CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE_STRING&response_type=token

Para que tu extremo de autorización controle las solicitudes de acceso, sigue estos pasos:

  1. Verifica los valores client_id y redirect_uri para evitar otorgar acceso a apps cliente no deseadas o mal configuradas:

    • Confirma que el client_id coincida con el ID de cliente que asignaste a Google.
    • Confirma que la URL que especifica el parámetro redirect_uri tenga el siguiente formato:
      https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID
      YOUR_PROJECT_ID es el ID que se encuentra en la página Configuración del proyecto de la Consola de Actions.
  2. Verifica si el usuario accedió a tu servicio. Si el usuario no accedió, completa el flujo de acceso o registro de tu servicio.

  3. Genera un token de acceso que Google usará para acceder a tu API. El token de acceso puede ser cualquier valor de string, pero debe representar de manera inequívoca al usuario y al cliente para el que se trata el token, y no debe ser adivinable.

  4. Envía una respuesta HTTP que redireccione el navegador del usuario a la URL que especifica el parámetro redirect_uri. Incluye todos los siguientes parámetros en el fragmento de URL:

    • access_token: Es el token de acceso que acabas de generar.
    • token_type: Es la cadena bearer.
    • state: Es el valor del estado sin modificar de la solicitud original. El siguiente es un ejemplo de la URL resultante:
      https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID#access_token=ACCESS_TOKEN&token_type=bearer&state=STATE_STRING

El controlador de redireccionamiento de OAuth 2.0 de Google recibirá el token de acceso y confirmará que el valor state no cambió. Después de que Google haya obtenido un token de acceso para tu servicio, lo adjuntará a las llamadas posteriores a tu acción como parte de AppRequest.

Inicia el flujo de autenticación

Usa el intent auxiliar de acceso a la cuenta para iniciar el flujo de autenticación. En los siguientes fragmentos de código, se describe cómo enviar una respuesta en Dialogflow y el SDK de Actions para usar este asistente.

Dialogflow:

Node.js
const {dialogflow, SignIn} = require('actions-on-google');
const app = dialogflow({
  // REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
  clientId: CLIENT_ID,
});
// Intent that starts the account linking flow.
app.intent('Start Signin', (conv) => {
  conv.ask(new SignIn('To get your account details'));
});
Java
@ForIntent("Start Signin")
public ActionResponse text(ActionRequest request) {
  ResponseBuilder rb = getResponseBuilder(request);
  return rb.add(new SignIn().setContext("To get your account details")).build();
}
JSON
{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "PLACEHOLDER"
            }
          }
        ]
      },
      "userStorage": "{\"data\":{}}",
      "systemIntent": {
        "intent": "actions.intent.SIGN_IN",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.SignInValueSpec",
          "optContext": "To get your account details"
        }
      }
    }
  },
  "outputContexts": [
    {
      "name": "/contexts/_actions_on_google",
      "lifespanCount": 99,
      "parameters": {
        "data": "{}"
      }
    }
  ]
}

SDK de Actions:

Node.js
const {actionssdk, SignIn} = require('actions-on-google');
const app = actionssdk({
  // REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
  clientId: CLIENT_ID,
});
// Intent that starts the account linking flow.
app.intent('actions.intent.TEXT', (conv) => {
  conv.ask(new SignIn('To get your account details'));
});
Java
@ForIntent("actions.intent.TEXT")
public ActionResponse text(ActionRequest request) {
  ResponseBuilder rb = getResponseBuilder(request);
  return rb.add(new SignIn().setContext("To get your account details")).build();
}
JSON
{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "PLACEHOLDER"
              }
            }
          ]
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.SIGN_IN",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.SignInValueSpec",
            "optContext": "To get your account details"
          }
        }
      ]
    }
  ],
  "conversationToken": "{\"data\":{}}",
  "userStorage": "{\"data\":{}}"
}

Controla las solicitudes de acceso a los datos

Si la solicitud de Asistente contiene un token de acceso, primero verifica que el token sea válido (y no haya vencido) y, luego, recupera la cuenta de usuario asociada de tu base de datos.