OAuth2: Autentica usuarios con Google

OAuth2 es el protocolo estándar de la industria para la autorización. Proporciona un mecanismo para que los usuarios otorguen a las aplicaciones web y de escritorio acceso a información privada sin compartir su nombre de usuario, contraseña y otras credenciales privadas.

En este instructivo, se crea una extensión que accede a los contactos de Google de un usuario mediante la API de Google People y la API de Chrome Identity. Debido a que las extensiones no se cargan mediante HTTPS, no pueden realizar redireccionamientos ni configurar cookies, dependen de la API de Chrome Identity para usar OAuth2.

Comenzar

Para comenzar, crea un directorio y los siguientes archivos de inicio.

La extensión completa y completa se puede descargar aquí.

manifest.json

Para agregar el manifiesto, crea un archivo llamado manifest.json e incluye el siguiente código. O descarga el archivo aquí.

{
  "name": "OAuth Tutorial FriendBlock",
  "version": "1.0",
  "description": "Uses OAuth to connect to Google's People API and display contacts photos.",
  "manifest_version": 2,
  "browser_action": {
    "default_title": "FriendBlock, friends face's in a block."
  },
  "background": {
    "scripts": [
      "background.js"
    ],
    "persistent": false
  }
}

background.js

Para agregar la secuencia de comandos en segundo plano, crea un archivo llamado background.js e incluye el siguiente código. También puedes descargar el archivo aquí.

chrome.browserAction.onClicked.addListener(function() {
  chrome.tabs.create({url: 'index.html'});
});

index.html

Agrega un archivo HTML llamado index.html y, luego, incluye el siguiente código. También puedes descargar el archivo aquí.

<html>
  <head>
    <title>FriendBlock</title>
    <style>
      button {
        padding: 10px;
        background-color: #3C79F8;
        display: inline-block;
      }
    </style>
  </head>
  <body>
    <button>FriendBlock Contacts</button>
    <div id="friendDiv"></div>
  </body>
</html>

Subir al panel del desarrollador

Empaqueta el directorio de la extensión en un archivo .zip y súbelo al Panel del desarrollador de Chrome sin publicarlo:

  1. En el Panel del desarrollador, haz clic en Agregar elemento nuevo.
  2. Haz clic en Choose file, selecciona el directorio de la extensión .zip y súbelo.
  3. Sin completar los campos adicionales, selecciona Guardar borrador y volver al panel.

Busca la extensión en Your Listings y haz clic en más información. En la ventana emergente, copia la clave pública y agrégala al manifiesto dentro del directorio descomprimido en el campo "key".

{
  "name": "OAuth Tutorial FaceBlcok",
...
  "key": "ThisKeyIsGoingToBeVeryLong/go8G...AQAB"
}

Comparar ID

Abre la página Administración de extensiones en chrome://extensions, asegúrate de que el modo de desarrollador esté habilitado y sube el directorio de extensiones sin empaquetar. Compara el ID de la extensión en la página de administración de extensiones con el ID de elemento en el Panel del desarrollador. Deberían coincidir.

El ID de la extensión coincide en todos los lugares

La extensión mantendrá el mismo ID incluyendo el campo "key" en el manifiesto. Preservar un solo ID es esencial para el registro de la API.

Crear ID de cliente de OAuth

Navega a la Consola de API de Google y crea un proyecto nuevo. Cuando esté todo listo, selecciona Credenciales en la barra lateral, haz clic en Crear credenciales y elige ID de cliente de OAuth.

Crea credenciales para la extensión

En la página Crear ID de cliente, selecciona App de Chrome. Completa el nombre de la extensión y coloca el ID de extensión al final de la URL en el campo ID de aplicación.

Completar la información de la extensión

Para finalizar, haz clic en Crear. La consola proporcionará un ID de cliente de OAuth.

Registrar OAuth en el manifiesto

Incluye el campo "oauth2" en el manifiesto de extensiones. Coloca el ID de cliente de OAuth generado en "client_id". Incluye una cadena vacía en "scopes" por ahora.

{
  "name": "OAuth Tutorial FriendBlock",
  ...
  "oauth2": {
    "client_id": "yourExtensionOAuthClientIDWillGoHere.apps.googleusercontent.com",
    "scopes":[""]
  },
  ...
}

Cómo iniciar el primer flujo de OAuth

Registra el permiso identity en el manifiesto.

{
  "name": "OAuth Tutorial FaceBlcok",
  ...
  "permissions": [
    "identity"
  ],
  ...
}

Crea un archivo para administrar el flujo de OAuth llamado oauth.js y, luego, incluye el siguiente código. También puedes descargarlo aquí.

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      console.log(token);
    });
  });
};

Coloca una etiqueta de secuencia de comandos para oauth.js en el encabezado de index.html.

...
  <head>
    <title>FriendBlock</title>
    ...
    <script type="text/javascript" src="oauth.js"></script>
  </head>
...

Vuelve a cargar la extensión y haz clic en el ícono del navegador para abrir index.html. Abre la consola y haz clic en el botón “FriendBlock Contacts”. Aparecerá un token de OAuth en la consola.

Cómo ver el token en la consola

Habilitar la API de Google People

Regresa a la consola de la API de Google y selecciona Biblioteca en la barra lateral. Busca "API de Google People", haz clic en el resultado correcto y habilítalo.

Habilitar la API de People

Agrega la biblioteca cliente de la API de Google People a "scopes" en el manifiesto de la extensión.

{
  "name": "OAuth Tutorial FaceBlcok",
  ...
  "oauth2": {
    "client_id": "yourExtensionOAuthClientIDWillGoHere.apps.googleusercontent.com",
    "scopes": [
      "https://www.googleapis.com/auth/contacts.readonly"
    ]
  },
  ...
}

Regresa a la consola de API de Google y navega a las credenciales. Haz clic en "Crear credenciales" y selecciona "Clave de API" en el menú desplegable.

Crear credenciales de la API de People

Conserva la clave de API generada para usarla más adelante.

Crear la primera solicitud a la API

Ahora que la extensión tiene los permisos y las credenciales adecuados, y puede autorizar a un usuario de Google, puede solicitar datos a través de la API de People. Actualiza el código en oauth.js para que coincida con lo siguiente.

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      let init = {
        method: 'GET',
        async: true,
        headers: {
          Authorization: 'Bearer ' + token,
          'Content-Type': 'application/json'
        },
        'contentType': 'json'
      };
      fetch(
          'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=API_KEY',
          init)
          .then((response) => response.json())
          .then(function(data) {
            console.log(data)
          });
    });
  });
};

Reemplaza API_KEY por la clave de API que se generó desde la Consola de APIs de Google. La extensión debe registrar un objeto JSON que incluya un array de people/account_id en el campo memberResourceNames.

Bloquear caras

Ahora que la extensión muestra una lista de los contactos del usuario, puede realizar solicitudes adicionales para recuperar los perfiles y la información de esos contactos . La extensión usará memberResourceNames para recuperar la información sobre fotos de los contactos de los usuarios. Actualiza oauth.js para incluir el siguiente código.

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      let init = {
        method: 'GET',
        async: true,
        headers: {
          Authorization: 'Bearer ' + token,
          'Content-Type': 'application/json'
        },
        'contentType': 'json'
      };
      fetch(
          'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=<API_Key_Here>',
          init)
          .then((response) => response.json())
          .then(function(data) {
            let photoDiv = document.querySelector('#friendDiv');
            let returnedContacts = data.memberResourceNames;
            for (let i = 0; i < returnedContacts.length; i++) {
              fetch(
                  'https://people.googleapis.com/v1/' + returnedContacts[i] +
                      '?personFields=photos&key=API_KEY',
                  init)
                  .then((response) => response.json())
                  .then(function(data) {
                    let profileImg = document.createElement('img');
                    profileImg.src = data.photos[0].url;
                    photoDiv.appendChild(profileImg);
                  });
            };
          });
    });
  });
};

Vuelve a cargar la extensión y regresa a ella. Haz clic en el botón FriendBlock y listo. Disfruta de las caras de los contactos en un bloque.

Caras de contacto en un bloque