使用 Google Drive API + Parse 将文件存储在单个 Drive 帐户上
Using Google Drive API + Parse to store files on a single Drive account
我正在尝试将单个 Google 云端硬盘帐户用作 'web server.' 我有一个 Android 应用程序需要能够存储和检索图片。我的想法是使用 Parse 来帮助管理一切并将我的存储容量扩展到 Parse 的免费数量之外。
基本上,我将拥有一个 Google 云端硬盘帐户和一个 Parse 项目。当用户想要存储文件时,he/she 将文件上传到 Parse,Parse 使用单个 Google Drive 帐户(使用 CloudCode)进行身份验证,Parse 将文件上传到 Drive,存储 URL 到 table 中的文件,并从 Parse 的云存储中删除该文件。我计划为存储这些文件的文件夹提供私有写入访问权限和 public 读取访问权限,这样客户端就不必向
发出解析请求
这样做的目的是为我的应用程序获取更多存储空间。 (Amazon S3 仅提供 5g,Parse 提供 1g,DropBox 2g,Google Cloud Storage 我认为他们没有免费计划,Drive 提供 15g 但我也听说 Google Photos 与Google 可以无限存储图片的驱动器)
因为 Google Drive 并非真正设计用于执行此操作,所以我很难弄清楚所有部分是如何组合在一起的。
我看过这个 question,它似乎不适用于我的情况,因为我将能够 运行 在安全服务器上进行所有写入操作。 (我也读过我需要存储一个刷新令牌,使用这种方法也应该是安全的)
我看过 this 但是很多链接都过时了,所以这对我帮助不大。
我看过 ,但这似乎是在授权某个应用使用用户的个人文件。
我也读到过,如果是 Web 应用程序帐户,我可能需要使用服务帐户,但同样,我阅读的信息还不是很清楚。在我看来,这是因为 Drive 并非设计为以这种方式工作。
总结:
1:
有人可以为我指明使用 Parse Cloud Code(服务器端 Javascript)将文件写入单个 Google Drive 帐户的正确方向吗?
2:
如果上面的问题是solvable/possible,Google发布Google照片是否意味着我的图片存储容量基本上是无限的?
好的。因此,经过数小时的研究和测试,我想出了一种让它发挥作用的方法。
Google 的 API 认证过程至少可以说有点混乱。大致流程如下:
- 要求用户授予范围
YOUR SCOPE
对 INSERT YOUR PROJECT HERE
的访问权限
- 用户可以接受或拒绝该请求
- 如果用户接受,您可以检索访问令牌(更重要的是刷新令牌)
- 获得刷新令牌后,您可以获得新的访问令牌,以便随时进行 API 调用。
因此,整个目标是进行 API 调用(特别是驱动),这需要刷新代码。
这方面的主要困难是,(据我所知)没有办法验证用户并获得访问 Parse CloudCode 中的代码。 但是,我有一个理论,如果我能够以某种方式在 CloudCode 之外验证用户帐户,您仍然可以 GET
/POST
来自 CloudCode 函数内部的请求。 (更具体地说:Parse.Cloud.httpRequest
)
有许多 ways/platforms 允许您对用户进行身份验证以获得刷新代码。最方便的方法可能是使用 API 的 Android/Java 版本,因为任何有计算机的人都可以 运行 一个 Android 模拟器,但我可以轻松访问 PHP 有能力的网站,所以我选择使用 PHP 代替。但是同样,这部分过程可以在许多不同的平台上完成。
第一步是安装 Google API Client Library for PHP (Github)。有几种不同的方法可以在您的服务器上安装它,但由于我只需要它来获取刷新令牌,我选择在 运行 时间动态包含它(也是因为我无法快速访问我的php.ini
个文件)。
(继续之前请注意:我不是 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));
}
?>
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));
}
?>
关于这段代码的几个重要说明:
- 您需要确保已创建 appropriate credentials(Web 应用程序)
- 您需要将正确的重定向 URI 添加到您的 OAuth 2.0 客户端 ID。它应该类似于
http://yourdomain.com/oauth2callback.php
.
- 您需要将
client_secrets.json
文件上传到您的服务器。您可以通过转到您的开发人员控制台并单击 OAuth 2.0 客户端 ID 列表最右侧的下载图标来获取它。
- 出于安全原因,您可能应该在复制刷新令牌后清除会话变量。
总而言之,我们创建了一个简单的程序,可以为特定用户打印出刷新令牌。您需要将该代码复制下来并保存以备后用。
即使您拥有刷新令牌,您仍需要一种获取访问令牌的方法来进行 API 调用。 (如果没有访问令牌,您将无法进行 API 调用,并且由于它们每 3600 秒过期一次,因此您需要一种在需要时获取新访问令牌的方法)
这是完成此步骤的 Parse CloudCode:
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);
});
});
此函数发送访问令牌请求。你可以用那个令牌做任何你想做的事;它存储在 httpResponse.text
中(如果请求成功)。请注意 grant_type
应该是 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);
});
});
此函数 returns 有关与该刷新令牌关联的驱动器帐户的信息。
关于我的第二个问题,我还没有做足够的研究来知道答案,但我计划找到并张贴在这里。
我正在尝试将单个 Google 云端硬盘帐户用作 'web server.' 我有一个 Android 应用程序需要能够存储和检索图片。我的想法是使用 Parse 来帮助管理一切并将我的存储容量扩展到 Parse 的免费数量之外。
基本上,我将拥有一个 Google 云端硬盘帐户和一个 Parse 项目。当用户想要存储文件时,he/she 将文件上传到 Parse,Parse 使用单个 Google Drive 帐户(使用 CloudCode)进行身份验证,Parse 将文件上传到 Drive,存储 URL 到 table 中的文件,并从 Parse 的云存储中删除该文件。我计划为存储这些文件的文件夹提供私有写入访问权限和 public 读取访问权限,这样客户端就不必向
发出解析请求这样做的目的是为我的应用程序获取更多存储空间。 (Amazon S3 仅提供 5g,Parse 提供 1g,DropBox 2g,Google Cloud Storage 我认为他们没有免费计划,Drive 提供 15g 但我也听说 Google Photos 与Google 可以无限存储图片的驱动器)
因为 Google Drive 并非真正设计用于执行此操作,所以我很难弄清楚所有部分是如何组合在一起的。
我看过这个 question,它似乎不适用于我的情况,因为我将能够 运行 在安全服务器上进行所有写入操作。 (我也读过我需要存储一个刷新令牌,使用这种方法也应该是安全的)
我看过 this 但是很多链接都过时了,所以这对我帮助不大。
我看过
我也读到过,如果是 Web 应用程序帐户,我可能需要使用服务帐户,但同样,我阅读的信息还不是很清楚。在我看来,这是因为 Drive 并非设计为以这种方式工作。
总结:
1:
有人可以为我指明使用 Parse Cloud Code(服务器端 Javascript)将文件写入单个 Google Drive 帐户的正确方向吗?
2:
如果上面的问题是solvable/possible,Google发布Google照片是否意味着我的图片存储容量基本上是无限的?
好的。因此,经过数小时的研究和测试,我想出了一种让它发挥作用的方法。
Google 的 API 认证过程至少可以说有点混乱。大致流程如下:
- 要求用户授予范围
YOUR SCOPE
对 - 用户可以接受或拒绝该请求
- 如果用户接受,您可以检索访问令牌(更重要的是刷新令牌)
- 获得刷新令牌后,您可以获得新的访问令牌,以便随时进行 API 调用。
INSERT YOUR PROJECT HERE
的访问权限
因此,整个目标是进行 API 调用(特别是驱动),这需要刷新代码。
这方面的主要困难是,(据我所知)没有办法验证用户并获得访问 Parse CloudCode 中的代码。 但是,我有一个理论,如果我能够以某种方式在 CloudCode 之外验证用户帐户,您仍然可以 GET
/POST
来自 CloudCode 函数内部的请求。 (更具体地说:Parse.Cloud.httpRequest
)
有许多 ways/platforms 允许您对用户进行身份验证以获得刷新代码。最方便的方法可能是使用 API 的 Android/Java 版本,因为任何有计算机的人都可以 运行 一个 Android 模拟器,但我可以轻松访问 PHP 有能力的网站,所以我选择使用 PHP 代替。但是同样,这部分过程可以在许多不同的平台上完成。
第一步是安装 Google API Client Library for PHP (Github)。有几种不同的方法可以在您的服务器上安装它,但由于我只需要它来获取刷新令牌,我选择在 运行 时间动态包含它(也是因为我无法快速访问我的php.ini
个文件)。
(继续之前请注意:我不是 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));
}
?>
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));
}
?>
关于这段代码的几个重要说明:
- 您需要确保已创建 appropriate credentials(Web 应用程序)
- 您需要将正确的重定向 URI 添加到您的 OAuth 2.0 客户端 ID。它应该类似于
http://yourdomain.com/oauth2callback.php
. - 您需要将
client_secrets.json
文件上传到您的服务器。您可以通过转到您的开发人员控制台并单击 OAuth 2.0 客户端 ID 列表最右侧的下载图标来获取它。 - 出于安全原因,您可能应该在复制刷新令牌后清除会话变量。
总而言之,我们创建了一个简单的程序,可以为特定用户打印出刷新令牌。您需要将该代码复制下来并保存以备后用。
即使您拥有刷新令牌,您仍需要一种获取访问令牌的方法来进行 API 调用。 (如果没有访问令牌,您将无法进行 API 调用,并且由于它们每 3600 秒过期一次,因此您需要一种在需要时获取新访问令牌的方法)
这是完成此步骤的 Parse CloudCode:
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);
});
});
此函数发送访问令牌请求。你可以用那个令牌做任何你想做的事;它存储在 httpResponse.text
中(如果请求成功)。请注意 grant_type
应该是 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);
});
});
此函数 returns 有关与该刷新令牌关联的驱动器帐户的信息。
关于我的第二个问题,我还没有做足够的研究来知道答案,但我计划找到并张贴在这里。