使用JavaScript授权Google云端硬盘

我试图授权我的应用程序与Google云端硬盘集成。 Google文档提供了各种服务器技术的基于服务器的授权和代码示例的详细信息

还有一个JavaScript Google API库,支持授权。 在wiki的样本部分中,有一个用于创建配置并调用授权功能的代码片段。 我已经将范围改变为我认为驱动器需要的范围:

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 Retrieve并使用OAuth 2.0 Credentials示例,客户端密钥似乎是参数,是否应该进入配置?

有没有人在JS,Drive或其他Google API上试过这个? 有没有人知道调试这样一个问题的最佳途径,也就是说,我是否需要一步步走过图书馆并停止呼喊?

请不要建议在服务器端进行授权,我们的应用程序完全是客户端,我不希望服务器上有任何状态(并且我理解这会导致令牌刷新问题)。 我熟悉Google控制台中的API配置,我相信和驱动器SDK设置是正确的。


可以在Drive上使用Google API Javascript客户端库,但是您必须知道存在一些问题。

目前有两个主要问题,两个都有工作周期:

授权

首先,如果仔细查看Google Drive验证的工作方式,您将会意识到,在用户安装了Drive应用程序并尝试打开文件或使用您的应用程序创建新文件后,Drive会自动启动OAuth 2.0授权流程, auth参数设置为response_type = codeaccess_type = offline 。 这基本上意味着现在Drive应用程序被迫使用OAuth 2服务器端流程,这对Javascript客户端库(仅使用客户端流程)没有任何用处。

问题是:Drive启动服务器端OAuth 2.0流程,然后Javascript客户端库启动客户端OAuth 2.0流程。

这仍然可以工作,您只需使用服务器端代码来处理在Drive服务器端流程之后返回的授权代码(您需要将它交换为访问令牌和刷新令牌)即可。 这样,只有在第一个流程中才会提示用户授权。 在您第一次交换授权码后,auth页面将被自动绕过。

服务器端样本可以在我们的文档中找到。

如果您不在服务器端流程中处理/交换授权码,每次尝试从Drive使用您的应用程序时,都会提示用户进行授权。

处理文件内容

第二个问题是我们的Javascript客户端库无法轻松上传和访问实际的Drive文件内容。 你仍然可以这样做,但你必须使用自定义的Javascript代码。

读取文件内容

当检索文件元数据/文件对象时,它包含指向实际文件内容的downloadUrl属性。 现在可以使用CORS请求下载文件,最简单的auth验证方式是在URL参数中使用OAuth 2访问令牌。 因此,只需将&access_token=...附加到downloadUrl然后使用XHR或通过将用户转发到URL来获取文件即可。

上传文件内容

更新来更新:上传终端现在支持CORS。

~~更新:上传端点,与其他Drive API不同,不支持CORS,因此您现在必须使用下面的技巧:~~

上传文件非常棘手,因为它不是内置在Javascript客户端库中,并且您无法完全按照此响应中的描述使用HTTP,因为我们不允许在这些API端点上进行跨域请求。 所以你必须利用我们的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 = "rn--" + boundary + "rn";
  const close_delim = "rn--" + 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/jsonrnrn' +
        JSON.stringify(metadata) +
        delimiter +
        'Content-Type: ' + contentType + 'rn' +
        'Content-Transfer-Encoding: base64rn' +
        'rn' +
        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上的CORS用于本地gDoc
  • 我们应该更容易使用我们的Javascript客户端库上传文件。
  • 没有承诺在这一点上虽然:)


    我做的。 下面是我的代码:

    <!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 Console上创建项目,激活云端硬盘API并在OAuth 2.0中激活Google帐户身份验证(实际上eeeeasy!)

    PS:它不会在你的电脑本地工作,它将在一些主机上工作,并且必须在项目控制台上提供它的网址:)

    链接地址: http://www.djcxy.com/p/63043.html

    上一篇: Authorization of Google Drive using JavaScript

    下一篇: Using Google OAuth2 with Flask