Autentica con una cuenta de usuario para apps instaladas

En esta guía, se explica cómo llevar a cabo autenticaciones con cuentas de usuario para acceder a la API de BigQuery cuando tu app se instala en las máquinas de los usuarios.

A fin de garantizar que la aplicación solo acceda a tablas de BigQuery que estén disponibles para el usuario final, realiza la autenticación con una credencial de usuario. Con una credencial de usuario se pueden ejecutar consultas solo con el proyecto de Google Cloud del usuario final, en lugar del proyecto de la app. Como resultado, al usuario se le facturan las consultas, en lugar de la app.

Antes de comenzar

  1. Crea un proyecto de Google Cloud Platform que represente la app instalada.
  2. Instala las bibliotecas cliente de BigQuery.
  3. Instala las bibliotecas requeridas.

    Python

    Instala la integración oauthlib para Google Auth.
    pip install --upgrade google-auth-oauthlib

    Node.js

    Instala la integración oauthlib para Google Auth.
    npm install google-auth-library
    npm install readline-promise

Configura tus credenciales de cliente

Usa el siguiente botón para seleccionar un proyecto y crear las credenciales necesarias.

Obtén credenciales

Crea credenciales de forma manual

  1. Ve a la página Credenciales de API en Google Cloud Console.
  2. Completa los campos obligatorios en la pantalla de consentimiento de OAuth.
  3. En la página Credenciales (Credentials), haz clic en el botón Crear credenciales (Create credentials).

    Elige el ID de cliente de OAuth.

  4. Selecciona Computadora de escritorio como el tipo de aplicación y, luego, haz clic en Crear.
  5. Haz clic en el botón Descargar JSON para obtener las credenciales.

    Descarga JSON.

    Guarda el archivo de credenciales en client_secrets.json. Este archivo se debe distribuir con tu app.

Autentica y llama a la API

  1. Usa las credenciales de cliente para realizar el flujo de OAuth 2.0.

    Python

    from google_auth_oauthlib import flow
    
    # TODO: Uncomment the line below to set the `launch_browser` variable.
    # launch_browser = True
    #
    # The `launch_browser` boolean variable indicates if a local server is used
    # as the callback URL in the auth flow. A value of `True` is recommended,
    # but a local server does not work if accessing the application remotely,
    # such as over SSH or from a remote Jupyter notebook.
    
    appflow = flow.InstalledAppFlow.from_client_secrets_file(
        'client_secrets.json',
        scopes=['https://www.googleapis.com/auth/bigquery'])
    
    if launch_browser:
        appflow.run_local_server()
    else:
        appflow.run_console()
    
    credentials = appflow.credentials

    Node.js

    const {OAuth2Client} = require('google-auth-library');
    const readline = require('readline-promise').default;
    
    function startRl() {
      const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
      });
    
      return rl;
    }
    
    /**
     * Download your OAuth2 configuration from the Google
     * Developers Console API Credentials page.
     * https://console.cloud.google.com/apis/credentials
     */
    const keys = require('./oauth2.keys.json');
    
    /**
     * Create a new OAuth2Client, and go through the OAuth2 content
     * workflow. Return the full client to the callback.
     */
    async function getRedirectUrl() {
      const rl = main.startRl();
      // Create an oAuth client to authorize the API call.  Secrets are kept in a `keys.json` file,
      // which should be downloaded from the Google Developers Console.
      const oAuth2Client = new OAuth2Client(
        keys.installed.client_id,
        keys.installed.client_secret,
        keys.installed.redirect_uris[0]
      );
    
      // Generate the url that will be used for the consent dialog.
      const authorizeUrl = oAuth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: 'https://www.googleapis.com/auth/bigquery',
        prompt: 'consent',
      });
    
      console.info(
        `Please visit this URL to authorize this application: ${authorizeUrl}`
      );
    
      const code = await rl.questionAsync('Enter the authorization code: ');
      const tokens = await main.exchangeCode(code);
      rl.close();
    
      return tokens;
    }
    
    // Exchange an authorization code for an access token
    async function exchangeCode(code) {
      const oAuth2Client = new OAuth2Client(
        keys.installed.client_id,
        keys.installed.client_secret,
        keys.installed.redirect_uris[0]
      );
    
      const r = await oAuth2Client.getToken(code);
      console.info(r.tokens);
      return r.tokens;
    }
    
    async function authFlow(projectId = 'project_id') {
      /**
       * TODO(developer):
       * Save Project ID as environment variable PROJECT_ID="project_id"
       * Uncomment the following line before running the sample.
       */
      // projectId = process.env.PROJECT_ID;
    
      const tokens = await main.getRedirectUrl();
    
      const credentials = {
        type: 'authorized_user',
        client_id: keys.installed.client_id,
        client_secret: keys.installed.client_secret,
        refresh_token: tokens.refresh_token,
      };
    
      return {
        projectId,
        credentials,
      };
    }
  2. Usa las credenciales autenticadas para conectarte a la API de BigQuery.

    Python

    from google.cloud import bigquery
    
    # TODO: Uncomment the line below to set the `project` variable.
    # project = 'user-project-id'
    #
    # The `project` variable defines the project to be billed for query
    # processing. The user must have the bigquery.jobs.create permission on
    # this project to run a query. See:
    # https://cloud.google.com/bigquery/docs/access-control#permissions
    
    client = bigquery.Client(project=project, credentials=credentials)
    
    query_string = """SELECT name, SUM(number) as total
    FROM `bigquery-public-data.usa_names.usa_1910_current`
    WHERE name = 'William'
    GROUP BY name;
    """
    query_job = client.query(query_string)
    
    # Print the results.
    for row in query_job.result():  # Wait for the job to complete.
        print("{}: {}".format(row['name'], row['total']))

    Node.js

    async function query() {
      const {BigQuery} = require('@google-cloud/bigquery');
    
      const credentials = await main.authFlow();
      const bigquery = new BigQuery(credentials);
    
      // Queries the U.S. given names dataset for the state of Texas.
      const query = `SELECT name, SUM(number) as total
      FROM \`bigquery-public-data.usa_names.usa_1910_current\`
      WHERE name = 'William'
      GROUP BY name;`;
    
      // For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query
      const options = {
        query: query,
      };
    
      // Run the query as a job
      const [job] = await bigquery.createQueryJob(options);
      console.log(`Job ${job.id} started.`);
    
      // Wait for the query to finish
      const [rows] = await job.getQueryResults();
    
      // Print the results
      console.log('Rows:');
      rows.forEach(row => console.log(row));
    
      return rows;
    }
    
    const main = {
      query,
      authFlow,
      exchangeCode,
      getRedirectUrl,
      startRl,
    };
    module.exports = {
      main,
    };
    
    if (module === require.main) {
      query().catch(console.error);
    }

Cuando ejecutas el código de muestra, se inicia un navegador que solicita acceso al proyecto asociado con los secretos del cliente. Puedes usar las credenciales que se generan para acceder a los recursos de BigQuery del usuario, ya que la muestra solicitó el alcance de BigQuery.

Próximos pasos

  1. Obtén más información sobre otras formas de autenticar tu app para acceder a la API de BigQuery.
  2. Obtén información sobre la autenticación con credenciales de usuario final para todas las API de Cloud.