Php 如何使用Google Drive API永久授权用户帐户将文件上载到驱动器?

Php 如何使用Google Drive API永久授权用户帐户将文件上载到驱动器?,php,google-api,google-drive-api,google-oauth,google-api-php-client,Php,Google Api,Google Drive Api,Google Oauth,Google Api Php Client,我正试图让我的web应用程序使用专用的电子邮件帐户通过API将文件上传到google drive。问题是,它一直要求潜在用户验证我为它准备的帐户,这正是我试图阻止的需要 我遇到的任何解决方案都指导我使用刷新令牌来确保帐户保持授权。这仍然伴随着一个问题,即在第一次使用时,用户必须对所述帐户进行身份验证。在本地保存带有刷新令牌的访问令牌不起作用,因为它仍然会强制新用户进行身份验证。 下面的代码段显示了用于身份验证的代码 class AccessDrive { private $client;

我正试图让我的web应用程序使用专用的电子邮件帐户通过API将文件上传到google drive。问题是,它一直要求潜在用户验证我为它准备的帐户,这正是我试图阻止的需要

我遇到的任何解决方案都指导我使用刷新令牌来确保帐户保持授权。这仍然伴随着一个问题,即在第一次使用时,用户必须对所述帐户进行身份验证。在本地保存带有刷新令牌的访问令牌不起作用,因为它仍然会强制新用户进行身份验证。 下面的代码段显示了用于身份验证的代码

class AccessDrive
{
    private $client;

    //initialize the client data provided on the call of the function
    private function initClient($scopes, $clientsecret, $returnUrl)
    {
        $client = new Google_Client();
        try{$client->setAuthConfig($clientsecret);}catch(Google_Exception $e){echo $e;}
        $client->setClientId(CLIENT_ID);
        $client->setApplicationName(APPLICATION_NAME);
        $client->setAccessType('offline');
        //$client->setApprovalPrompt('force');
        $client->setIncludeGrantedScopes(true);   // incremental auth
        foreach ($scopes as $scope) { 
            $client->addScope($this->getScope($scope)); //assume one or multiple from the google drive scopes
        }
        $client->setRedirectUri( $returnUrl);
        return $client;
    }

    public function Login()
    {
        if (!$_SESSION['code']) {
            $auth_url = $this->client->createAuthUrl();
            header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
        } else {
            error_reporting(-1 & ~E_WARNING);
            $this->client->authenticate($_SESSION['code']);
        }
        return false;
    } 

    public function __construct($returnUrl, $scopes, $clientSecret)
    {
        $this->client = $this->initClient($scopes, $clientSecret, $returnUrl);
        $this->Login();
    }
}
?>
如何确保应用程序不需要提示用户进行身份验证,在用户应该访问的功能之外保持身份验证

-->编辑: 在DaImTo尝试实现建议的方法后,以下代码生成一个Google_Service_异常,指出客户端无权使用此方法检索访问令牌。我不知道哪里出了问题

class AccessDrive
{
    private $client;

    public function __construct( $scopes, $credentials, $email, $toImpersonate )
    {
        putenv( "GOOGLE_APPLICATION_CREDENTIALS=".$credentials);
        $scopelist =[];
        foreach ($scopes as $scope) {
            array_push($scopelist, $this->getScope($scope));
        }
        $client = new Google_Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope($scopelist);
        $client->setSubject($toImpersonate);
        $this->client = $client;
    }
-->编辑:
如果你投反对票,我想知道为什么,这样我可以改进我现在和将来的问题。

你目前正在使用Oauth2进行创作。Oauth2允许您请求用户访问其google驱动器帐户。假设他们授予您访问权限,您将获得一个访问令牌,允许您访问他们的数据一小时。如果您请求脱机访问,您将获得一个刷新令牌,当访问令牌过期时,您可以使用该令牌请求新的访问令牌

在您的情况下,因为您试图访问自己的驱动器帐户,所以我建议您考虑改用服务帐户。服务帐户是预先批准的,您可以与谷歌驱动器帐户共享一个文件夹,只要您不删除权限,谷歌驱动器帐户就可以访问该驱动器帐户。我有一篇关于服务账户如何运作的帖子

例如:

// Load the Google API PHP Client Library.
require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
 * Gets the Google client refreshing auth if needed.
 * Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
 * Initializes a client object.
 * @return A google client object.
 */
function getGoogleClient() {
    return getServiceAccountClient();
}
/**
 * Builds the Google client object.
 * Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
 * Scopes will need to be changed depending upon the API's being accessed. 
 * array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
 * List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
 * @return A google client object.
 */
function getServiceAccountClient() {
    try {   
        // Create and configure a new client object.        
        $client = new Google_Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope([YOUR SCOPES HERE]);
        return $client;
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}
代码从我的示例项目中删除

用法:

require_once __DIR__ . '/vendor/autoload.php';
session_start();
require_once __DIR__ . '/ServiceAccount.php';     
$client = getGoogleClient();
$service = new Google_Service_Drive($client); 

然后使用
$service

发送您的所有请求。首先,非常感谢您的回答,服务帐户绝对是最好的选择。然而,它给我带来了一个谷歌服务的例外,从那以后我就一直无法解决这个问题。它声明我的客户机无权在此方法中检索AccessToken。你觉得我错过了什么吗?我已经在答案中添加了新的代码片段。在google开发者控制台中,确保您创建了一个客户端类型的服务帐户。您可以创建不同类型的客户端。我可以选择几个角色,但它不允许我选择服务帐户的类型。关于这类事情的文档对我来说是非常不清楚的,也许我遗漏了一些东西,但即使在添加了几个不同的角色来尝试让事情发生之后,我仍然不知道如何让它工作。你是在谷歌开发者控制台上做这件事的,对吗?那里的角色一点也不重要。单击create credentials->service account keyyes,我正在控制台中执行此操作。我已经试过了,但它仍然不允许我通过我的应用程序访问Google Drive,并发出同样的错误。我还共享了我应该访问的驱动器中的文件夹。让我觉得我缺乏某种许可,或者我的代码出了问题