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

使用Google Drive API解析在单个驱动器帐户上存储文件

宋昕
2023-03-14

我正在尝试使用一个Google Drive帐户作为“web服务器”我有一个Android应用程序,需要能够存储和检索图片。我的想法是使用Parse来帮助管理一切,并将我的存储容量扩展到Parse的可用容量之外。

从本质上讲,我将拥有一个Google云端硬盘帐户和一个解析项目。当用户想要存储文件时,他/她会将文件上传到解析,解析使用单个Google云端硬盘帐户(使用CloudCode)进行身份验证,解析将文件上传到云端硬盘,将文件的URL存储在表格中,然后从解析的云存储中删除文件。我计划为存储这些文件的文件夹提供私人写入访问权限和公共读取访问权限,以便客户端不必向

这样做的目的是为我的应用程序获得更多的存储空间。(亚马逊S3只给5g,Parse给1g,DropBox 2g,谷歌云存储我不认为他们有免费计划,Drive给15g但我也听说过Google Photos与Google Drive集成,这可能会给我无限的图片存储空间)

因为Google云端硬盘并不是真正为此而设计的,所以我很难弄清楚所有部分是如何组合在一起的。

我已经看过这个问题,它似乎不适用于我的情况,因为我将能够在安全的服务器上运行我所有的写入操作。(我也读过我需要存储一个刷新令牌,使用这种方法也应该是安全的)

我已经看过了,但是很多链接都已经过时了,所以对我没什么帮助。

我已经看过了,但这似乎是授权应用程序使用用户的个人文件。

我还读到,如果是Web应用程序帐户,我可能需要使用服务帐户,但同样,我读到的信息不太清楚。在我看来,这是因为驱动器不是这样设计的。

摘要:

有人可以为我指出正确的方向,使用解析云代码(服务器端Javascript)将文件写入单个Google云端硬盘帐户吗?

如果上述问题是可以解决/可能的,那么谷歌发布谷歌照片是否意味着我将拥有基本上无限的图片存储容量?

共有1个答案

璩浩广
2023-03-14

好的。经过几个小时的研究和测试,我想出了一个让它发挥作用的方法。

至少可以说,谷歌的API身份验证过程有点令人困惑。一般步骤如下:

  1. 用户被要求授予对的访问权限。请在此处插入您的项目。用于您的范围
  2. 用户可以接受或拒绝该请求。
  3. 如果用户接受,您可以检索访问令牌(更重要的是刷新令牌)
  4. 一旦您拥有了刷新令牌,您就可以获得一个新的访问令牌,以便随时进行API调用

因此,这样做的全部目的是进行API调用(特别是对drive ),这需要刷新代码。

这方面的主要困难是,(据我所知)无法在Parse CloudCode中验证用户并获取访问代码。但是,我有一个理论,如果我能够以某种方式在CloudCode之外验证用户帐户,您仍然可以从CloudCode函数内部发出<code>GET</code>/<code>POST</code>请求。(更具体地说:Parse.Cloud.httpRequest

有许多方法/平台允许您对用户进行身份验证以获取刷新代码。最容易访问的方法可能是使用Android / Java版本的API,因为任何有计算机的人都可以运行Android模拟器,但我可以轻松访问具有PHP功能的网站,所以我选择使用PHP代替。但同样,该过程的这一部分可以在许多不同的平台上完成。

第一步是安装用于PHP的Google API客户端库(Github)。有几种不同的方法可以在您的服务器上安装它,但由于我只需要它来获得刷新令牌,所以我选择在运行时动态地包含它(也因为我无法快速访问我的<code>php.ini<code>文件)。

(在我继续之前请注意:我不是PHP开发人员,所以如果我做任何奇怪或多余的事情,请告诉我;我只是在展示我做了什么来让它工作)

为此,我只需下载该库的副本,将其上传到我的服务器,并在我使用该库的所有文件中包含以下行:

set_include_path(get_include_path() . PATH_SEPARATOR . 'google-api-php-client-master/src');

其中google-api-php-client-master/src是src文件夹的路径。

一旦你完成了这些,你必须对用户进行认证。以下两个文件将用户发送到身份验证页面,然后在屏幕上打印该用户的刷新代码。

index.php代码:

<?php
    set_include_path(get_include_path() . PATH_SEPARATOR . 'google-api-php-client-master/src');
    require_once 'google-api-php-client-master/src/Google/autoload.php'; // or wherever autoload.php is located 

    session_start();

    $client = new Google_Client();
    $client->setAuthConfigFile('client_secrets.json'); //You can download this file from your developer console under OAuth 2.0 client IDs
    $client->addScope(Google_Service_Drive::DRIVE); //Scope that grants full access to user's Google Drive
    $client->setAccessType("offline"); //Important so a refresh code is returned

    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
        print($_SESSION['refresh_token']);
    } else {
        $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
        header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }
?>

< code>oauth2callback.php:

<?php

    set_include_path(get_include_path() . PATH_SEPARATOR . 'google-api-php-client-master/src');

    require_once 'google-api-php-client-master/src/Google/autoload.php';

    session_start();

    $client = new Google_Client();
    $client->setAuthConfigFile('client_secrets.json');
    $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
    $client->addScope(Google_Service_Drive::DRIVE);
    $client->setAccessType("offline");

    if (! isset($_GET['code'])) {
      $auth_url = $client->createAuthUrl();
      header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
    } else {
      $client->authenticate($_GET['code']);
      $_SESSION['access_token'] = $client->getAccessToken();
      $_SESSION['refresh_token'] = $client->getRefreshToken(); //Important to clear the session variable after you have the token saved somewhere
      $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/'; //Redirects to index.php
      header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }

?>

关于此代码的几个重要注意事项:

  1. 您需要确保已创建适当的凭据(Web 应用程序
  2. 您需要将正确的重定向 URI 添加到 OAuth 2.0 客户端 ID。它应该是 http://yourdomain.com/oauth2callback.php 的东西。
  3. 您需要将client_secrets.json 文件上传到服务器。您可以通过转到开发人员控制台并单击 OAuth 2.0 客户端 ID 列表最右侧的下载图标来获取此信息。
  4. 出于安全原因,在复制刷新令牌后,您可能应该清除会话变量。

总之,我们创建了一个简单的程序,为特定用户打印出刷新令牌。你需要把那段代码复制下来,保存起来以备后用。

即使您有刷新令牌,您也需要一种获取访问令牌以进行API调用的方法。(没有访问令牌就无法进行API调用,因为它们每3600秒过期一次,所以您需要一种在需要时获取新令牌的方法)

以下是用于完成此步骤的解析云代码:

Parse.Cloud.define("getAccessToken", function(request, response) {
    Parse.Cloud.httpRequest({
        method: "POST",
        url: 'https://www.googleapis.com/oauth2/v3/token/',
        params: {
            refresh_token : 'INSERT_REFRESH_TOKEN_HERE',
            client_id : 'INSERT_CLIENT_ID_HERE',
            client_secret : 'INSERT_CLIENT_SECRET_HERE',
            grant_type : 'refresh_token'
        }
    }).then(function(httpResponse) {
      response.success(httpResponse.text);
    }, function(httpResponse) {
      response.error('Request failed with response code ' + httpResponse.status);
    });
});

这个函数发送一个访问令牌的请求。你可以用这个令牌做任何你想做的事情;它存储在< code>httpResponse.text中(如果请求成功)。请注意,< code>grant_type应该是< code>refresh_token而不是您的刷新令牌。

一旦有了访问令牌,就可以在刷新令牌的范围内自由地进行API调用。示例:

Parse.Cloud.define("sendRequest", function(request, response) {
    Parse.Cloud.httpRequest({
        method: "GET",
        url: 'https://www.googleapis.com/drive/v2/about',
        params: {
            access_token : 'INSERT_YOUR_ACCESS_TOKEN_HERE'
        }
    }).then(function(httpResponse) {
      response.success(httpResponse.text);
    }, function(httpResponse) {
      response.error('Request failed with response code ' + httpResponse.status);
    });
});

此函数返回与刷新令牌关联的驱动器帐户的信息。

关于我的第二个问题,我还没有做足够的研究来知道答案,但我计划找到答案并发布在这里。

 类似资料: