Autentificarse con las Google APIs en Javascript

Hace poco me vi en la necesidad de preparar un fotoblog usando Blogger y Panoramio con el requisito indispensable de no tener que usar el backend de Blogger para editar los posts. Creé un acceso alternativo usando una página estática oculta pero se me presento el problema de autentificar a los editores y decidí implementar la autentificación con OAuth 2.0.
En primer lugar debemos solicitar a Google que nos de acceso al API que nos interesa. Entramos en la API Console - Services y pulsamos Request Access... en Blogger API v3. Nos pedirá el nombre que queremos dar a nuestra aplicación y una pequeña explicación sobre qué queremos hacer. Lo enviamos y en menos de 24 horas recibiremos un email suministrándonos un enlace a la sección API Access, donde encontraremos nuestra API Key. Con esta clave podremos cargar la API solicitada y usar los servicios disponibles pero para autentificar a un usuario necesitamos algo más, necesitamos poder acceder a sus datos personales, en este caso a su dirección de correo GMail, para comprobar en nuestra propia lista si es un usuario legítimo. Para ello crearemos una identificación para aplicaciones web con OAuth 2.0. Pulsamos en Create Client Id y respondemos al cuestionario: si es una aplicación web o se instala en el pc, en cual lenguaje se va a codificar y desde cuales dominios se debe permitir el acceso. En este caso es una aplicación web programada en Javascript y el dominio es el fotoblog de mi amigo en Blogger. También solicita una url para redireccionar pero en Javascript no es necesaria. Hecho esto se nos proporciona el Client ID que necesitaremos para autentificarnos como usuarios de la aplicación. Ya disponemos del material básico para empezar a trabajar.
Necesitamos cargar la librería cliente de Javascript con la etiqueta:
<script src="https://apis.google.com/js/client.js?key=tu_API_KEY&onload=handleClientLoad"></script>
La función handleClientLoad() es la que se ejecutará en cuanto la librería esté cargada y donde empezamos a implementar la autentificación:
function handleClientLoad()
{
      window.setTimeout(checkAuth, 1);
}
Esta función simplemente llama al inicio del proceso de autentificación, se define aparte por si necesita ser llamado posteriormente:
var clientID = 'tu_ClientID';
var scopes = 'https://www.googleapis.com/auth/blogger https://www.googleapis.com/auth/blogger.readonly https://www.blogger.com/feeds/ https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email';
 
function checkAuth()
{
      gapi.auth.authorize({
        'client_id': clientID,
        'scope': scopes,
        'immediate': true,
        'response_type': 'token id_token'
      }, handleAuthResult);
}
Llamamos al método auth.authorize suministrándole:

  • el clientID
  • los scopes (ámbitos), para informar al sistema a qué datos queremos que nos de acceso, en este caso al email del usuario entre otros, puedes ver una lista de scopes en ThreeDigitIQ
  • el modo: inmediato para que efectúe la autentificación sin mostrar la pantalla de solicitud de datos del usuario (email + clave)
  • el tipo de respuesta: el token de la conexión
  • el procedimiento a llamar tras realizar la comprobación: handleAuthResult

La función handleAuthResult() comprueba si el usuario es legítimo, si lo es pasamos a comprobar el acceso a nuestro blog, en caso contrario, volvemos a solicitar el login.
function handleAuthResult(authResult)
{
 if (authResult && !authResult.error) // Si el usuario es legítimo
    makeApiCall();
 else
  myLogin();
}
La función myLogin() simplemente vuelve a llamar a auth.authorize pero con el modo inmediato a false por lo que se presentará la pantalla de solicitud de datos al usuario:
function myLogin()
{
 gapi.auth.authorize({'client_id': clientID,
  'scope': scopes,
  'immediate': false,
  'response_type': 'token id_token'
 }, handleAuthResult);
   return false;
}
En makeApiCall() ya tenemos acceso al API de Google. Lo que vamos a hacer es solicitar los datos del usuario para tener acceso a su email y poder contrastarlo con los datos de usuarios guardados en nuestro blog:
function makeApiCall()
{
 gapi.client.load('oauth2', 'v2', function()  // Cargamos la librería de autentificación
 {
        var request = gapi.client.oauth2.userinfo.get();  // Solicitamos info del usuario
    request.execute(function (response)
  {
   if (!response.code) // Si code == undefined : datos ok
   {
       token.access_token = token.id_token;
         gapi.auth.setToken(token);
    accessMail = response.email;  // Guardamos el email para usarlo en la siguiente función
    gapi.client.load('blogger', 'v3', runApi); // Cargamos el API de Blogger v3
   }
   else
    myLogin();
  });
 });  
}
Si todo va bien client.oauth2.userinfo.get nos devuelve los datos solicitados en formato JSON en el objeto response, en caso contrario devolverá un mensaje de error también en formato JSON con un campo code, si este campo existe ya sabemos que algo ha fallado por lo que volvemos a solicitar el login, en caso contrario se carga el API de Blogger y se llama a la función runApi(). En esta cargaremos un post previamente guardado en nuestro blog donde hemos almacenado los datos de los usuarios a los que queremos permitir el acceso. El formato (JSON) de dicho post es:
{ "editor": [ { "email": "elmaildeleditor@mail.com" } ] }
var blogID = 'id_del_blog';
var editorsID = 'id_del_post_con_datos_usuarios';

function runApi()
{
  var request = gapi.client.blogger.posts.get(  // Solicitamos el post
  {
     'blogId': blogID,
  'postId': editorsID,
  'fields': 'content'
  });
     request.execute(function(response)
  {
  var respuesta = JSON.parse(response.content);
  var idxEditor = buscaEditor(respuesta, accessMail);  // Buscamos si coincide el mail del editor con el autentificado
  if (idxEditor != null)
  {
   // Aquí podemos obtener los datos que nos interesen del editor
  }
  else
  {
   gapi.auth.setToken(null);
   myLogin();
  }
  });
}
buscaEditor() es una simple función que recorre el objeto JSON respuesta con los datos de usuarios   buscando el email y devolviendo null si no lo encuentra. Si lo encuentra podemos iniciar las funciones de nuestro programa, en caso contrario volvemos a solicitar login.
Y eso es todo. No he comprobado si el sistema de tokens que proporciona OAuth 2.0 permite hacer lo mismo, lo que me interesaba era empezar a manejarme con las API de Google. Para ver las funciones disponibles según cada API y probarlas para ver como funcionan puedes entrar en Google APIs Explorer.

No hay comentarios:

Publicar un comentario