Revive nuestro webinar Ver Ahora

Ucampus avanza: Optimizando desarrollos con OAuth

Tomás Ahumada
Tomás Ahumada
Ingeniero de Desarrollo

El primer proyecto que desarrollé para el Centro Tecnológico Ucampus fue un módulo para sincronizar archivos de los cursos de la plataforma con la cuenta Google Drive de los usuarios. Un usuario puede configurar los cursos cuyos archivos se subirán a su Google Drive, y cuando un archivo se suba a uno de sus cursos este se subirá automáticamente a su cuenta de Google Drive.

Esta funcionalidad requirió que implementara mi primera conexión OAuth para realizar la conexión entre un usuario y su cuenta de Google Drive.

Cuando terminamos el proyecto, el director del Centro me comentó que esta no era la primera conexión OAuth que el sistema hacía. Y hablamos de que sería cómodo hacer una especie de wrapper para simplificar este tipo de conexiones para el desarrollador. Así fue como durante las siguientes semanas creamos la librería OAuth de Ucampus.

La librería tiene 2 funciones principales: “init” y “api”.

 
init

La función “init” recibe el nombre del servicio a conectar, el id del usuario y un booleano llamado dont_connect (cuyo valor por defecto es falso). Al llamar esta función con un usuario y un servicio, revisa si el usuario ya tiene su cuenta conectada con el servicio. Si es que no la tiene, envía al usuario a la pantalla de autorización del servicio, obtiene el access y refresh token y los guarda en el sistema.

Si el usuario ya tiene la cuenta conectada usamos el access token para acceder al servicio. Y si el access token está vencido, usamos el refresh token para obtener un nuevo access token. Si llamamos la función con el parámetro dont_connect en verdadero, entonces no intentamos conectar al usuario, sólo revisamos si el usuario hizo la conexión.

Finalmente, la función retorna un booleano que representa si el usuario está conectado.

Cuando queremos acceder al servicio desde uno de nuestros scripts, siempre llamamos a esta función primero y vemos si es que retornó verdadero. En cuyo caso la conexión se hizo con éxito y podemos hacer llamadas al api con la siguiente función.

 
api

La función “api” usa los tokens del usuario para hacer llamadas al api del servicio al que nos conectamos por OAuth. Recibe una url, los datos a enviar, el método (GET, POST, DELETE, PUT), el tipo de contenido a recibir (“application/json” por defecto) y un booleano llamado return_plain que define el formato de los datos que entrega esta función (si los entrega como diccionario o como texto). 

Esta función tiene mucho más código que init, ya que se encarga de definir todas las operaciones de curl. Además, se encarga de los casos en que los tokens venzan después de hacer el init, pero antes de hacer la llamada a esta función. Cuando pasa esto último, intentamos reconectar una vez, esto es, usar el refresh token para pedir un nuevo access token. Si eso no funciona llamamos a la url con los parámetros y anteriores y retornamos en texto plano el resultado de la llamada.

Distintos servicios tienen diferentes mensajes de error para decirnos que nuestros tokens no son válidos. Por esto, dentro de esta función tenemos un diccionario de mensajes de error por tokens inválidos de servicios con los que nos hemos conectado. Así comparamos si el mensaje retornado es un mensaje de error y si es que corresponde a tokens inválidos dado el servicio al que llamamos.

 
Atributos

Meses después, usamos esta librería para implementar el módulo de “Colaboraciones”. Este módulo permite a los usuarios crear archivos en Google Docs, Slides y Sheets sin preocuparse de setear los permisos del archivo. U-Cursos le da permiso a editar el archivo sólo a la gente a la que el usuario le comparte.

Sin embargo, en el módulo queríamos mostrar datos sobre el archivo para mostrar una lista con los comentarios que hacían los usuarios en Google Drive. El problema es que no es trivial asociar un correo a un usuario de nuestra plataforma sólo con las dos funciones de arriba. Por eso creamos “Atributos”, que son metadatos de la conexión.

Usando los atributos, guardamos ahí el correo de la persona y lo asociamos a su id en la plataforma. Así pudimos asociar al autor de cada comentario a un usuario de nuestra plataforma para mostrarlo. Para los mensajes de usuarios no registrados mostramos su correo solamente.

El cómo está implementado esto es a través de la función “attr” la cual recibe dos parámetros, llamémoslos ‘k’ y ‘v'. Si se llama con solo un parámetro la función adopta el comportamiento de un getter, es decir, retorna los datos guardados usando ‘k’ como llave. Si se llama con dos parámetros adopta el comportamiento de un setter, guardando los contenidos de ‘v’ usando la llave ‘k’.

Conclusión

En resumen, la librería ahorra un montón de código al no tener que implementar cada conexión OAuth por separado. Antes, cada conexión OAuth requería alrededor de 80 líneas de código entre las configuraciones de los requests usando curl y el manejo de los casos borde. Ahora, en el peor de los casos, el servicio con el que nos queremos conectar no tiene un mensaje de tokens inválidos estándar y hay que extender el diccionario de mensajes de error de la librería para detectarlo.

Los atributos también ahorran el trabajo de crear una tabla para cada conexión en la base de datos, siempre y cuando los metadatos guardados no sean muy grandes.

Teléfono Comercial
+56 2 32477538
+56 9 87151650
Email
info@ucampus.cl
Dirección
Avda. Pedro de Valdivia 0193 Oficina 32.
Providencia, Santiago
Chile

Suscrí­bete a nuestro newsletter