43

アプリケーションを承認して Google ドライブと統合しようとしています。Google のドキュメントには、サーバー ベースの承認の詳細と、さまざまなサーバー テクノロジのコード サンプルが記載されています。

承認をサポートするJavaScript Google API ライブラリもあります。wikiのサンプル セクションの下に、構成を作成してauthorize 関数を呼び出すためのコード スニペットがあります。ドライブに必要であると思われる範囲にスコープを変更しました。

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

コールバック関数は決して呼び出されません (はい、Google API ライブラリは修正されてロードされます) Java の取得と OAuth 2.0 資格情報の使用の例を見ると、クライアント シークレットはパラメーターのようですが、これを構成に入れる必要がありますか?

ドライブや他の Google API のために、JS でこれを試した人はいますか? このような問題をデバッグするための最良の方法を知っている人はいますか?

サーバー側で承認を行うことを提案しないでください。私たちのアプリケーションは完全にクライアント側です。サーバー上で状態を望んでいません (これが引き起こすトークンの更新の問題を理解しています)。私は Google コンソールの API 構成に精通しており、ドライブ SDK の設定は正しいと思います。

4

2 に答える 2

61

ドライブで Google API Javascript クライアント ライブラリを使用することは可能ですが、いくつかの問題点があることに注意する必要があります。

現在、2 つの主な問題があり、どちらにも回避策があります。

認可

まず、Google ドライブの認証がどのように機能するかをよく見てみると、ユーザーがドライブ アプリケーションをインストールし、アプリケーションでファイルを開くか新しいファイルを作成しようとすると、ドライブが OAuth 2.0 認証フローを自動的に開始し、認証パラメーターはresponse_type=codeおよびaccess_type=offlineに設定されます。これは基本的に、現在ドライブ アプリが OAuth 2 サーバー側フローを使用することを余儀なくされていることを意味します。これは Javascript クライアント ライブラリ (クライアント側フローのみを使用します) には何の役にも立ちません。

問題は、ドライブがサーバー側の OAuth 2.0 フローを開始し、次に Javascript クライアント ライブラリがクライアント側の OAuth 2.0 フローを開始することです。

これは引き続き機能します。必要なのは、サーバー側のコードを使用して、ドライブのサーバー側フローの後に返された認証コードを処理することだけです (アクセス トークンと更新トークンに交換する必要があります)。そうすれば、最初のフローでのみ、ユーザーに承認を求めるプロンプトが表示されます。初めて認証コードを交換した後、認証ページは自動的にバイパスされます。

これを行うためのサーバー側のサンプルは、 ドキュメントで入手できます。

サーバー側フローで認証コードを処理/交換しない場合、ユーザーはドライブからアプリを使用しようとするたびに認証を求められます。

ファイル コンテンツの処理

2 つ目の問題は、Google の Javascript クライアント ライブラリを使用すると、実際のドライブ ファイル コンテンツのアップロードとアクセスが簡単に行えないことです。引き続き実行できますが、カスタム Javascript コードを使用する必要があります。

ファイルの内容の読み取り

ファイル メタデータ/ファイル オブジェクトが取得さdownloadUrlれると、実際のファイル コンテンツを指す属性が含まれます。CORS リクエストを使用してファイルをダウンロードできるようになりました。最も簡単な認証方法は、URL パラメーターで OAuth 2 アクセス トークンを使用することです。そのため、 XHR を使用するか、ユーザーを URL に転送することによって、ファイルに追加&access_token=...してフェッチするだけです。downloadUrl

ファイルコンテンツのアップロード

更新の更新: アップロード エンドポイントCORS をサポートするようになりました。

~~UPDATE: Drive API の残りの部分とは異なり、アップロード エンドポイントは CORS をサポートしていないため、今のところ以下のトリックを使用する必要があります:~~

ファイルのアップロードは、Javascript クライアント ライブラリに組み込まれていないため注意が必要です。また、これらの API エンドポイントでのクロスドメイン リクエストが許可されていないため、この応答で説明されているように HTTP で完全に行うことはできません。そのため、Javascript クライアント ライブラリで使用される iframe プロキシを利用し、それを使用して、構築されたマルチパート リクエストを Drive SDK に送信する必要があります。@Alainのおかげで、以下にその方法のサンプルがあります。

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

これらすべてを改善するために、将来的には次の可能性があります。

  • 開発者が使用する OAuth 2.0 フロー (サーバー側またはクライアント側) を選択できるようにするか、開発者が OAuth フロー全体を処理できるようにします。
  • /upload/...エンドポイントで CORS を許可する
  • exportLinksネイティブ gDocs でCORS を許可する
  • Javascript クライアント ライブラリを使用して、ファイルのアップロードを簡単にする必要があります。

ただし、この時点では約束はありません:)

于 2012-04-26T10:13:14.007 に答える
14

やったよ。私のコードは次のとおりです。

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

変更する必要があるのは次のとおりです。

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

Google API コンソールから clientID と ApiKey に:)

もちろん、Google API コンソールでプロジェクトを作成し、Drive API を有効にして、OAuth 2.0 で Google アカウント認証を有効にする必要があります (非常に簡単です!)。

PS: あなたの PC でローカルに動作することはありません。一部のホスティングでは動作しますが、プロジェクト コンソールでその URL を提供する必要があります :)

于 2012-07-01T07:24:08.400 に答える