Autoryzacja Dysku Google za pomocą JavaScript

Próbuję autoryzować moją aplikację do integracji z Dyskiem Google. Dokumentacja Google zawiera szczegóły autoryzacji serwerowej i próbki kodu dla różnych technologii serwerowych .

Istnieje również JavaScript Google API library , która ma wsparcie dla autoryzacji. W sekcji samples na wiki znajduje się fragment kodu do tworzenia konfiguracji i wywoływania authorize function. Zmieniłem zakres tak, żeby był taki. believe is required for drive:

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

Funkcja callback nigdy nie jest wywoływana (tak, biblioteka Google API jest ładowana poprawiona) patrząc na przykład poświadczeń Java Retrieve and Use OAuth 2.0, tajemnica klienta wydaje się być parametrem, czy powinno to wejść do konfiguracji?

Czy ktoś próbował tego w JS, na dysk lub inne API Google? Czy ktoś zna najlepszą drogę do debugowania takiego problemu, tzn. czy muszę po prostu przejść przez bibliotekę i przestać narzekać?

Proszę nie sugeruj autoryzacji po stronie serwera, nasza aplikacja jest całkowicie po stronie klienta, nie chcę żadnego stanu na serwerze(i Rozumiem problemy z odświeżaniem tokenów, które spowodują). Jestem zaznajomiony z konfiguracją API w konsoli Google i uważam, że i ustawienie SDK dysku są poprawne.

Author: David, 2012-04-26

2 answers

Możliwe jest korzystanie z biblioteki klienta JavaScript API Google z dyskiem, ale musisz mieć świadomość, że są pewne problemy.

Obecnie istnieją 2 główne problemy, z których oba mają workarrounds:

Autoryzacja

Po pierwsze, jeśli przyjrzysz się dokładnie, jak działa Google Drive auth, zdasz sobie sprawę, że po zainstalowaniu aplikacji Dysku przez użytkownika i próbie otwarcia pliku lub utworzenia nowego pliku z aplikacją, Drive inicjuje OAuth 2.0 autoryzacja przebiega automatycznie, a parametry auth są ustawione na response_type = code i access_type = offline . Oznacza to, że w tej chwili aplikacje na dyski są zmuszone do korzystania z przepływu po stronie serwera OAuth 2, który nie będzie w żaden sposób przydatny dla biblioteki klienta Javascript (która używa tylko przepływu po stronie klienta).

Problem polega na tym, że: Drive inicjuje przepływ po stronie serwera OAuth 2.0, następnie Biblioteka klienta Javascript inicjuje przepływ po stronie klienta OAuth 2.0 / align = "left" /

To może nadal działać, wystarczy użyć kodu po stronie serwera, aby przetworzyć kod autoryzacyjny zwrócony po stronie serwera dysku (musisz go wymienić na token dostępu i token odświeżania). W ten sposób tylko przy pierwszym przepływie użytkownik zostanie poproszony o autoryzację. Po pierwszej wymianie kodu autoryzacyjnego strona auth zostanie automatycznie pominięta.

Próbki po stronie serwera dostępne są w naszym dokumentacja .

Jeśli nie przetworzysz/nie wymienisz kodu auth po stronie serwera, użytkownik zostanie poproszony o auth za każdym razem, gdy spróbuje użyć Twojej aplikacji z dysku.

Obsługa zawartości pliku

Druga kwestia polega na tym, że przesyłanie i uzyskiwanie dostępu do rzeczywistej zawartości dysku nie jest łatwe przez naszą bibliotekę klientów Javascript. Nadal możesz to zrobić, ale będziesz musiał użyć niestandardowego kodu Javascript.

Odczyt pliku content

Gdy pobierane są metadane pliku/obiekt pliku, zawiera on atrybut downloadUrl, który wskazuje na rzeczywistą zawartość pliku. Teraz Można pobrać plik za pomocą żądania CORS i najprostszym sposobem auth jest użycie tokenu dostępu OAuth 2 w param URL. Więc po prostu dołącz {[2] } do downloadUrl i pobierz plik za pomocą XHR lub przekierowując użytkownika do adresu URL.

Przesyłanie zawartości pliku

UPDATE UPDATE: the upload endpoints do now wsparcie CORS.

~ ~ UPDATE: punkty końcowe wysyłania, w przeciwieństwie do reszty interfejsu API dysku nie obsługują CORS, więc na razie musisz użyć poniższej sztuczki:~ ~

Przesyłanie pliku jest trudne, ponieważ nie jest wbudowany w lib klienta Javascript i nie możesz zrobić tego całkowicie za pomocą HTTP, jak opisano w ta odpowiedź , ponieważ nie zezwalamy na żądania między domenami na tych punktach końcowych API. Musisz więc skorzystać z serwera iframe proxy używanego przez naszą bibliotekę klientów Javascript i użyć to, aby wysłać skonstruowane żądanie wieloczęściowe do SDK dysku. Dzięki @Alain, mamy próbkę jak to zrobić poniżej:

/**
 * 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);
  }
}

Aby to wszystko poprawić, w przyszłości możemy:]}
  • pozwól programistom wybrać przepływ OAuth 2.0, którego chcą użyć (po stronie serwera lub po stronie klienta) lub pozwól deweloperowi całkowicie zająć się przepływem OAuth.
  • pozwól KORSOM na /upload/... punkty końcowe
  • [58]}pozwól CORS na exportLinks dla natywnych gDocs
  • we should make it łatwiejsze przesyłanie plików za pomocą naszej biblioteki klienta Javascript.

W tym momencie jednak żadnych obietnic:)

 53
Author: Nivco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:00

Udało mi się. Heres mój kod:

<!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>

Musisz tylko zmienić:

  • var clientId = '######';
  • var apikey = "aaaaaaaaaaaaaaaaa";

Do twojego klienta i ApiKey z konsoli Google API:)

Oczywiście musisz stworzyć swój projekt na konsoli Google API, aktywować Drive API i aktywować konta Google auth w OAuth 2.0 (naprawdę eeeeasy!)

PS: nie będzie działać lokalnie na twoim komputerze, będzie działać na jakimś hostingu, a yoy musi podaj adres url z niego na konsoli projektu:)

 12
Author: InsaurraldeAP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-01 07:24:08