当前位置: 首页 > 知识库问答 >
问题:

使用JavaScript授权Google Drive

阴靖
2023-03-14

我正在尝试授权我的应用程序与Google Drive集成。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检索和使用OAuth 2.0凭证示例,客户端机密似乎是一个参数,这应该放入配置中吗?

有没有人尝试过JS、for Drive或其他Google API?有没有人知道调试这样一个问题的最佳途径,即我是否只需要一步一步地浏览库并停止Whiging?

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

共有2个答案

祁远
2023-03-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>

你只需要改变:

    < li > var clientId = ' # # # # # # < Li > var API key = ' aaaaaaaaaaaaaaaaaaaa ';

到您的客户端 ID 和 apiKey 从您的谷歌 API 控制台:)

当然你得在Google API控制台上创建你的项目,激活Drive API并在OAuth 2.0中激活Google Accounts auth(真的eeeeasy!)

PS:它不会在您的PC上本地工作,它会在一些主机上工作,并且yoy必须在项目控制台上提供它的url:)

林君博
2023-03-14

可以将Google API Javascript客户端库与Drive一起使用,但您必须注意存在一些痛点。

目前有两个主要问题,这两个问题都有解决方法:

首先,如果仔细观察Google Drive auth的工作原理,您会发现,用户安装了驱动器应用程序并尝试打开文件或使用应用程序创建新文件后,驱动器会自动启动OAuth 2.0授权流,auth参数设置为response_type=code和access_type=offline。这基本上意味着,现在驱动应用程序被迫使用OAuth 2服务器端流,这对Javascript客户端库(只使用客户端流)没有任何用处。

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

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

在我们的文档中可以找到实现这一点的服务器端示例。

如果您不处理/交换服务器端流上的身份验证代码,则每次尝试从Drive使用您的应用程序时,都会提示用户进行身份验证。

第二个问题是,通过我们的 Javascript 客户端库,上传和访问实际的云端硬盘文件内容并不容易。您仍然可以这样做,但您必须使用自定义的 Javascript 代码。

读取文件内容

检索文件元数据/文件对象时,它包含指向实际文件内容的 downloadUrl 属性。现在可以使用 CORS 请求下载文件,最简单的身份验证方法是在 URL 参数中使用 OAuth 2 访问令牌。所以只需附加

上传文件内容

更新更新:上传endpoint现在支持CORS。

~~更新:与驱动器API的其他部分不同,上传endpoint不支持CORS,因此您现在必须使用以下技巧:~~

上传一个文件很棘手,因为它不是内置在Javascript客户端库中的,而且你不能像在这个响应中描述的那样完全用HTTP来完成,因为我们不允许在这些APIendpoint上跨域请求。因此,您必须利用我们的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 流。
  • 允许在 /上传/... 终结点上使用 CORS
  • 允许在导出时使用 CORS 将链接用于本机 gDocs
  • 我们应该使用我们的 Javascript 客户端库更轻松地上传文件。

不过在这一点上没有promise:)

 类似资料:
  • Using a delegation key The collaborator can now push to the repository using Docker Content Trust. Docker will automatically choose and pick the right key for the targets/release role. Edit the file o

  • 问题内容: 我正在尝试授权我的应用程序与Google云端硬盘集成。Google文档提供了有关基于服务器的授权的详细信息以及各种服务器技术的代码示例。 还有一个JavaScript Google API库,该库支持授权。在Wiki的示例部分下方有一个代码片段,用于创建配置和调用authorize函数。我将范围更改为我认为需要驱动器的范围: 永远不会调用该回调函数(是的,已更正了GoogleAPI库的

  • 我目前正在尝试设置一个对一个具有基本授权的REST API(Cloudsight)的POST请求。到目前为止我的代码是: null null 当我尝试并运行它时,我得到错误:Uncatted SyntaxError:无法对“XMLHttpRequest”执行“set requestHeader”:“authorization:”不是有效的HTTP头字段名。 有人知道代码出了什么问题吗?我对Java

  • API使用步骤 成为目睹云认证用户 登录控制台https://www.wenjiangs.com/doc/QSfBOXSPconsole/, 进入系统管理下的TOKEN管理。 使用第二步中得到的TOKEN,便可以访问目睹云API中的全部接口服务,如果请求没有带上TOKEN,目睹云API的安全机制将会视其为未授权访问操作,并将其拦截。 API域名 https://www.muducloud.com

  • 我想写一个应用程序,允许与数据交互的两种RESTful形式;常规REST CRUDendpoint和Web-UI。 过去,我在JS中实现了UI的大部分功能,这将调用常规的RESTendpoint。这很好,但对于这个应用程序,我想使用Qute来执行生成页面内容的大部分基本功能。但是,为了正确地管理endpoint并确保正确的RBAC控制,我需要通过cookie而不是普通的头来访问JWT。这似乎是可能

  • 介绍 除了内置的 用户认证 服务之外, Lumen 还提供了用户授权和资源访问控制的方案。有很多种方法与辅助函数能帮你处理授权逻辑。 总的来说,Lumen 中的使用和 Laravel 大同小异,我们会在这个文档中指出不同的地方,完整的用户授权文档还需要查阅 Laravel 授权文档 。 与 Laravel 的不同 定义权限 与 Laravel 相比,Lumen 的用户授权的不同之处在于如何定义权限