使用Google Drive API + Parse将文件存储在单个云端硬盘帐户中 [英] Using Google Drive API + Parse to store files on a single Drive account

查看:188
本文介绍了使用Google Drive API + Parse将文件存储在单个云端硬盘帐户中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将一个Google云端硬盘帐户用作网络服务器。我有一个Android应用需要能够存储和检索图片。我的想法是使用Parse来帮助管理所有事情,并将存储容量扩展到Parse的免费金额以外。



实质上,我将拥有一个Google Drive帐户和一个Parse项目。当用户想要存储文件时,他/她将文件上传到Parse,使用单个Google云端硬盘帐户进行Parse身份验证(使用CloudCode),Parse将文件上传到云端硬盘,将URL存储到文件中并删除该文件来自Parse的云存储。我打算给存储这些文件的文件夹提供私人写入访问和公共读取访问权限,以便客户端不必向Parse请求发送请求。



这样做的目的是为我的应用程序获得更多存储。 (Amazon S3只提供5g,Parse提供1g,DropBox 2g,Google云端存储我认为他们没有免费计划,Drive提供15g,但我也听说Google Photos与Google Drive集成可能会给我无限的存储空间因为Google Drive的设计并不是真正的这样做,所以我有些难以理解所有的部分如何组合在一起。



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



我已经看过这个,但很多链接已经过时,所以没有太大帮助。



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

我也读过我可能需要使用服务帐户,而不是Web应用程序帐户,但同样,我一直在阅读的信息并不十分清楚。在我看来,这是因为Drive没有被设计成以这种方式工作。



总结:
$ b

1:



是否有人能指出我使用Parse Cloud代码(服务器端JavaScript)将文件写入单个Google云端硬盘帐户的正确方向?



2:



如果上述问题可以解决/可能,Google的Google Photo这意味着我将拥有基本无限的图片存储容量吗? 确定。所以在经过数小时的研究和测试之后,我想出了一个让这个工作起作用的方法。

至少可以说Google的API认证过程有点混乱。一般程序如下:


  1. 要求用户授予对 INSERT YOUR PROJECT HERE 您的范围

  2. 用户可以接受或拒绝该请求

  3. 如果用户接受,您可以检索访问令牌(更重要的是刷新令牌)。
  4. 一旦拥有刷新令牌,您就可以获得一个新的访问令牌来进行API调用你需要的时间。

因此,其整体目标是进行需要刷新代码的API调用(特别是驱动器)。 / p>

主要困难在于,( 我认识的 )无法验证用户并获取Parse CloudCode内部的访问代码。 ,我有一个理论,如果我能以某种方式验证CloudCode之外的用户帐户,您仍然可以使 GET / POST 来自CloudCode函数内部的请求。 (更具体地说: Parse.Cloud.httpRequest



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



第一步是安装适用于PHP的Google API客户端库 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-客户主/ SRC');
require_once'google-api-php-client-master / src / Google / autoload.php'; //或autoload.php所在的位置

session_start();

$ client = new Google_Client();
$ client-> setAuthConfigFile('client_secrets.json'); //您可以从OAuth 2.0客户端ID
$ client-> addScope(Google_Service_Drive :: DRIVE)下的开发者控制台下载此文件; //授予用户Google Drive完全访问权限的范围
$ client-> setAccessType(offline); //重要,所以刷新代码被返回

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); $!
$ b 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(); //将令牌保存在某处后清除会话变量的重要事项
$ redirect_uri ='http://'。 $ _SERVER ['HTTP_HOST']。 /; //重定向到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 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'
} $然后(function(httpResponse){
response.success(httpResponse.text);
},function(httpResponse){
response.error('Request failed with response代码'+ httpResponse.status);
});
});

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



获得访问令牌后,您可以在刷新令牌的范围内自由进行API调用。例子:

pre $ 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);
});
});

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






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


I am trying to use a single Google Drive account as a 'web server.' I have an Android app that needs to be able to store and retrieve pictures. My idea was to use Parse to help manage everything and extend my storage capacity beyond Parse's free amount.

Essentially, I will have a single Google Drive account and a Parse project. When a user wants to store a file, he/she uploads the file to Parse, Parse authenticates with the single Google Drive account (using CloudCode), Parse uploads the files to Drive, stores the URL to the file in a table, and deletes the file from Parse's cloud storage. I plan on giving the folder that stores these files private write access and public read access so the clients don't have to make Parse requests to

The purpose of this is to get more storage for my application. (Amazon S3 only gives 5g, Parse gives 1g, DropBox 2g, Google Cloud Storage I don't think they have a free plan, and Drive gives 15g but I have also heard about Google Photos integrating with Google Drive which might give me unlimited storage for pictures)

Because Google Drive wasn't really designed to do this, I am having some difficultly figuring out how all the pieces fit together.

I have looked at this question which doesn't seem to apply to my situation because I will be able to run all my write operations on a secure sever. (Also I have read I need to store a refresh token which should also be secure using this method)

I have looked at this but many of the links are outdated, so that didn't help me much.

I have looked at this, but this seems to be authorizing an app's use of the user's personal files.

I have also read that I may need to use a service account instead if a Web Application account, but again, the information I have been reading has not been very clear. In my opinion, this is because Drive was not designed to work this way.

Summary:

1:

Can someone point me in the right direction for writing files to a single Google Drive account using Parse Cloud Code (Server-side Javascript)?

2:

If the above question is solvable/possible, does Google's release of Google Photo's mean that I would have essentially unlimited storage capacity for pictures?

解决方案

OK. So after hours of research and testing, I have come up with a way of getting this to work.

Google's API authentication process is a bit confusing to say the least. The general procedure is as follows:

  1. User is asked to grant access to INSERT YOUR PROJECT HERE for the scope YOUR SCOPE
  2. The user can either accept or reject that request
  3. If the user accepts, you can retrieve an access token (and more importantly a refresh token)
  4. Once you have the refresh token you can get a new access token to make API calls any time you want.

So the whole goal of this is to make API calls (specifically to drive) which requires a refresh code.

The main difficulty in this is, (AS FAR AS I KNOW) there is no way of authenticating a user and getting an access code inside of Parse CloudCode. BUT, I had a theory that if I was somehow able to authenticate the user account outside of CloudCode, you could still make GET/POST requests from inside a CloudCode function. (More specifically: Parse.Cloud.httpRequest)

There are many ways/platforms that allow you to authenticate a user in order to get a refresh code. The most accessible method would probably be by using the Android/Java version of the API because anyone with a computer can run an Android emulator, but I have easy access to a PHP capable website, so I chose to use PHP instead. But again, this part of the process can be done on many different platforms.

The first step is to install the Google API Client Library for PHP (Github). There are a few different ways to install this on your server, but since I only need it to get a refresh token, I chose to include it dynamically at runtime (also because I didn't have quick access to my php.ini file).

(Note before I continue: I am not a PHP developer, so please let me know if I do anything odd or redundant; I am merely showing what I did to get this to work)

To do this I simply downloaded a copy of the library, uploaded it to my server, and included the following line in all the files I used the library:

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

Where google-api-php-client-master/src is the path to your src folder.

Once you have that done, you have to authenticate the user. The following two files send the user to an authentication page, and then print the refresh code for that user on the screen.

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));
    }

?>

Several important notes about this code:

  1. You need to make sure you have created the appropriate credentials (Web application)
  2. You need to add the correct redirect URI to your OAuth 2.0 client ID. It should be something like http://yourdomain.com/oauth2callback.php.
  3. You need to have uploaded your client_secrets.json file to your server. You can get this by going to your developers console and clicking the download icon on the far right side of the OAuth 2.0 client IDs list.
  4. You should probably clear your session variables after you copy the refresh token down for security reasons.

So in summary, we have created a simple program that prints out the refresh token for a specific user. You need to copy that code down and save it for later.

Even though you have the refresh token, you need a way of getting an access token to make API calls. (You can't make an API call without an access token, and because they expire every 3600 seconds, you need a way of getting a new one when you need it)

Here is the Parse CloudCode for accomplishing this step:

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);
    });
});

This function sends a request for an access token. You can do whatever you want with that token; it is stored in httpResponse.text (if the request was successful). Note that grant_type should be refresh_token not YOUR refresh token.

Once you have an access token, you are free to make API calls within the scope of your refresh token. Example:

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);
    });
});

This function returns information about the drive account associated with that refresh token.


With regards to my second question, I have not done enough research to know the answer to that yet, but I plan on finding out and posting it here.

这篇关于使用Google Drive API + Parse将文件存储在单个云端硬盘帐户中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆