node google javascript oauth-2.0 google-drive-sdk

javascript - node - npm google drive



AutorizaciĆ³n de Google Drive usando JavaScript (2)

Es posible utilizar la biblioteca del cliente de JavaScript de las API de Google con Drive, pero debe tener en cuenta que existen algunos puntos negativos.

En este momento hay 2 problemas principales, los cuales tienen workarrounds:

Autorización

Primero, si observa detenidamente cómo funciona Google Drive, se dará cuenta de que, después de que un usuario haya instalado su aplicación Drive e intente abrir un archivo o crear un nuevo archivo con su aplicación, Drive inicia automáticamente el flujo de autorización de OAuth 2.0 los parámetros de autenticación se establecen en response_type = code y access_type = offline . Esto básicamente significa que en este momento las aplicaciones de Drive están obligadas a usar el flujo del lado del servidor OAuth 2 que no va a ser útil para la biblioteca del cliente de Javascript (que solo usa el flujo del lado del cliente).

El problema es que: Drive inicia un flujo de OAuth 2.0 del lado del servidor, luego la biblioteca de cliente de JavaScript inicia un flujo de OAuth 2.0 del lado del cliente.

Esto aún puede funcionar, todo lo que tiene que hacer es usar el código del lado del servidor para procesar el código de autorización devuelto después del flujo del lado del servidor de Drive (necesita intercambiarlo por un token de acceso y un token de actualización). De esta forma, solo en el primer flujo se le solicitará autorización al usuario. Después de la primera vez que intercambias el código de autorización, la página de autenticación se omitirá automáticamente.

Las muestras del lado del servidor para hacer esto están disponibles en nuestra documentación .

Si no procesa / intercambia el código de autenticación en el flujo del lado del servidor, se le pedirá al usuario la autenticación cada vez que intente utilizar su aplicación desde Drive.

Manejo del contenido del archivo

El segundo problema es que la biblioteca cliente de Javascript no facilita la carga y el acceso al contenido real del archivo Drive. Aún puede hacerlo, pero deberá usar un código JavaScript personalizado.

Leyendo el contenido del archivo

Cuando se recupera un metadata de archivo / un objeto de archivo, contiene un atributo downloadUrl que apunta al contenido real del archivo. Ahora es posible descargar el archivo utilizando una solicitud CORS y la forma más sencilla de autenticar es usar el token de acceso OAuth 2 en un parámetro de URL. Simplemente agregue &access_token=... a downloadUrl y busque el archivo usando XHR o reenvíe al usuario a la URL.

Subir contenido del archivo

ACTUALIZACIÓN DE ACTUALIZACIÓN: los puntos finales de carga ahora son compatibles con CORS.

~~ ACTUALIZACIÓN: los puntos finales de carga, a diferencia del resto de la API de Drive, no son compatibles con CORS, por lo que tendrás que usar el truco siguiente por ahora: ~~

Cargar un archivo es complicado porque no está incorporado en la biblioteca del cliente de Javascript y no puedes hacerlo completamente con HTTP como se describe en esta respuesta porque no permitimos solicitudes de dominios cruzados en estos puntos finales API. Por lo tanto, debe aprovechar el proxy iframe utilizado por nuestra biblioteca cliente de Javascript y usarlo para enviar una solicitud multiparte construida al SDK de Drive. Gracias a @Alain , tenemos una muestra de cómo hacerlo a continuación:

/** * Insert new file. * * @param {File} fileData File object to read data from. * @param {Function} callback Callback function to call when the request is complete. */ function insertFileData(fileData, callback) { const boundary = ''-------314159265358979323846''; const delimiter = "/r/n--" + boundary + "/r/n"; const close_delim = "/r/n--" + boundary + "--"; var reader = new FileReader(); reader.readAsBinaryString(fileData); reader.onload = function(e) { var contentType = fileData.type || ''application/octet-stream''; var metadata = { ''title'': fileData.fileName, ''mimeType'': contentType }; var base64Data = btoa(reader.result); var multipartRequestBody = delimiter + ''Content-Type: application/json/r/n/r/n'' + JSON.stringify(metadata) + delimiter + ''Content-Type: '' + contentType + ''/r/n'' + ''Content-Transfer-Encoding: base64/r/n'' + ''/r/n'' + base64Data + close_delim; var request = gapi.client.request({ ''path'': ''/upload/drive/v2/files'', ''method'': ''POST'', ''params'': {''uploadType'': ''multipart''}, ''headers'': { ''Content-Type'': ''multipart/mixed; boundary="'' + boundary + ''"'' }, ''body'': multipartRequestBody}); if (!callback) { callback = function(file) { console.log(file) }; } request.execute(callback); } }

Para mejorar todo esto, en el futuro podríamos:

  • Permita que los desarrolladores elijen qué flujo de OAuth 2.0 desean usar (del lado del servidor o del lado del cliente) o permita que el desarrollador maneje el flujo de OAuth por completo.
  • Permitir CORS en los puntos finales /upload/...
  • Permitir CORS en los exportLinks de exportLinks para gDocs nativos
  • Deberíamos facilitar la carga de archivos utilizando nuestra biblioteca cliente de JavaScript.

Sin promesas en este momento, aunque :)

Intento autorizar que mi aplicación se integre con Google Drive. La documentación de Google proporciona detalles para la autorización basada en servidor y muestras de código para varias tecnologías de servidor .

También hay una biblioteca API de Google JavaScript , que tiene soporte para autorización. Abajo en la sección de ejemplos de la wiki hay un fragmento de código para crear una configuración y llamar a la función autorizar . He alterado el alcance para que sea el que creo que se requiere para la unidad:

var config = { ''client_id'': ''my_client_ID'', ''scope'': ''https://www.googleapis.com/auth/drive.file'' }; gapi.auth.authorize(config, function() { console.log(gapi.auth); });

La función de devolución de llamada nunca se llama (sí, la biblioteca de la API de Google se carga correctamente) Mirando el ejemplo de Recuperación de Java y Usar Credenciales de OAuth 2.0, el secreto del cliente parece ser un parámetro, ¿debería esto entrar en la configuración?

¿Alguien ha intentado esto en JS, para Drive u otras API de Google? ¿Alguien sabe cuál es la mejor ruta para eliminar este problema, es decir, si necesito pasar por la biblioteca y dejar de aullar?

Por favor no sugiera hacer la autorización en el lado del servidor, nuestra aplicación es completamente del lado del cliente, no quiero ningún estado en el servidor (y entiendo los problemas de actualización del token que esto causará). Estoy familiarizado con la configuración de la API en la consola de Google y creo que la configuración del SDK de la unidad es correcta.


Lo hice. Aquí está mi código:

<!DOCTYPE html> <html> <head> <meta charset=''utf-8'' /> <style> p { font-family: Tahoma; } </style> </head> <body> <!--Add a button for the user to click to initiate auth sequence --> <button id="authorize-button" style="visibility: hidden">Authorize</button> <script type="text/javascript"> var clientId = ''######''; var apiKey = ''aaaaaaaaaaaaaaaaaaa''; // To enter one or more authentication scopes, refer to the documentation for the API. var scopes = ''https://www.googleapis.com/auth/drive''; // Use a button to handle authentication the first time. function handleClientLoad() { gapi.client.setApiKey(apiKey); window.setTimeout(checkAuth,1); } function checkAuth() { gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult); } function handleAuthResult(authResult) { var authorizeButton = document.getElementById(''authorize-button''); if (authResult && !authResult.error) { authorizeButton.style.visibility = ''hidden''; makeApiCall(); } else { authorizeButton.style.visibility = ''''; authorizeButton.onclick = handleAuthClick; } } function handleAuthClick(event) { gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult); return false; } // Load the API and make an API call. Display the results on the screen. function makeApiCall() { gapi.client.load(''drive'', ''v2'', function() { var request = gapi.client.drive.files.list ( {''maxResults'': 5 } ); request.execute(function(resp) { for (i=0; i<resp.items.length; i++) { var titulo = resp.items[i].title; var fechaUpd = resp.items[i].modifiedDate; var userUpd = resp.items[i].lastModifyingUserName; var fileInfo = document.createElement(''li''); fileInfo.appendChild(document.createTextNode(''TITLE: '' + titulo + '' - LAST MODIF: '' + fechaUpd + '' - BY: '' + userUpd )); document.getElementById(''content'').appendChild(fileInfo); } }); }); } </script> <script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script> <p><b>These are 5 files from your GDrive :)</b></p> <div id="content"></div> </body> </html>

Solo tienes que cambiar:

  • var clientId = ''######'';
  • var apiKey = ''aaaaaaaaaaaaaaaaaaa'';

a su ID de cliente y ApiKey desde su Consola API de Google :)

Por supuesto, debe crear su proyecto en la Consola de API de Google, activar la API de Drive y activar la autenticación de cuentas de Google en OAuth 2.0 (¡muy fácil!)

PD: no funcionará localmente en tu PC, funcionará en algunos hosting, y deberás proporcionar la URL desde la consola del proyecto :)