我正在尝试使用单个Google云端硬盘帐户作为网络服务器。'我有一个Android应用程序,需要能够存储和检索图片。我的想法是使用Parse来帮助管理所有内容并将我的存储容量扩展到Parse的免费金额之外。
基本上,我将拥有一个Google云端硬盘帐户和一个Parse项目。当用户想要存储文件时,他/她将文件上传到Parse,Parse使用单个Google Drive帐户进行身份验证(使用CloudCode),Parse将文件上传到Drive,将URL存储到表中的文件中,然后删除来自Parse云存储的文件。我打算给存储这些文件的文件夹提供私有写访问和公共读访问权限,这样客户就不必向Parse请求发送
这样做的目的是为我的应用程序获得更多存储空间。 (亚马逊S3只提供5g,Parse提供1g,DropBox 2g,谷歌云存储我不认为他们有免费计划,而驱动器提供15g,但我也听说过谷歌照片集成谷歌驱动器可能会给我无限存储图片)
由于谷歌硬盘并没有真正做到这一点,我有一些难以弄清楚如何将所有部分组合在一起。
我已经查看了question这似乎不适用于我的情况,因为我将能够在安全服务器上运行所有写操作。 (我还读过我需要存储一个刷新令牌,使用这种方法也应该是安全的)
我看过this,但很多链接已经过时了,所以对我没什么帮助。
我查看了this,但这似乎是在授权应用使用用户的个人文件。
我还读过,如果是Web应用程序帐户,我可能需要使用服务帐户,但同样,我一直在阅读的信息还不是很清楚。在我看来,这是因为Drive不是以这种方式工作的。
要点:
有人能指出我使用Parse Cloud Code(服务器端Javascript)将文件写入单个Google云端硬盘帐户的正确方向吗?
如果上述问题可以解决/可能,那么Google发布的Google Photo是否意味着我的图片存储空间基本无限?
答案 0 :(得分:2)
行。因此,经过数小时的研究和测试,我想出了一种让它发挥作用的方法。
Google的API身份验证过程至少可以说有点令人困惑。一般程序如下:
INSERT YOUR PROJECT HERE
YOUR SCOPE
的访问权限
因此,这样做的全部目标是进行需要刷新代码的API调用(特别是驱动)。
主要的困难是,( AS FAR AS I WOW )无法验证用户并获取Parse CloudCode内的访问代码。 但是 ,我有一个理论认为,如果我能以某种方式验证CloudCode之外的用户帐户,您仍然可以GET
/ POST
来自CloudCode函数的请求。 (更具体地说:Parse.Cloud.httpRequest
)
有许多方法/平台允许您对用户进行身份验证以获取刷新代码。最容易访问的方法可能是使用Android / Java版本的API,因为任何拥有计算机的人都可以运行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));
}
?>
关于此代码的几个重要说明:
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);
});
});
此函数返回有关与该刷新令牌关联的驱动器帐户的信息。
关于我的第二个问题,我还没有做足够的研究来了解答案,但我打算在此找到并发布。