Google api 如何通过Google/apiclient从PHP使用googledriveapi的API键

Google api 如何通过Google/apiclient从PHP使用googledriveapi的API键,google-api,google-drive-api,google-api-php-client,api-key,service-accounts,Google Api,Google Drive Api,Google Api Php Client,Api Key,Service Accounts,我希望我的PHP web应用程序在特定的google帐户(不是任意用户的帐户,而是我们公司的特定帐户)中创建电子表格 我已经测试过的和有效的 我需要google/apiclientPHP客户端库。它正在运行 我的控制器中有这些私有方法: private function getGoogleDriveService( string $scopes ) : \Google_Service_Drive { $client = $this->getClient( $scopes );

我希望我的PHP web应用程序在特定的google帐户(不是任意用户的帐户,而是我们公司的特定帐户)中创建电子表格

我已经测试过的和有效的 我需要
google/apiclient
PHP客户端库。它正在运行

我的控制器中有这些私有方法:

private function getGoogleDriveService( string $scopes ) : \Google_Service_Drive
{
    $client = $this->getClient( $scopes );

    $service = new \Google_Service_Drive( $client );

    return $service;
}

private function getClient( string $scopes ) : \Google_Client
{
    $client = new \Google_Client();

    $client->setApplicationName( 'My nice application name.' );
    $client->setAuthConfig( $this->getSecretPath() );
    $client->setScopes( $scopes );
    $client->setAccessType( 'offline' );

    return $client;
}

private function getSecretPath() : string
{
    $projectDir = $this->get( 'kernel' )->getProjectDir();
    $credentialsFullPath = $projectDir . '/app/config/googleApiSecret.json';

    return $credentialsFullPath;
}
我调用
getGoogleDriveService
告诉特定控制器操作需要哪些作用域来创建Google服务。该服务首先通过调用
getClient
来创建,它返回一个初始化的
\Google\u Client
对象,该对象依次获得传递给它的
凭证.json
路径

到目前为止,一切顺利。这很有效

例如,使用如下代码:

$driveService = $this->getGoogleDriveService( \Google_Service_Drive::DRIVE );

$file = new \Google_Service_Drive_DriveFile();
$file->setName( 'My nice dummy file' );
$file->setMimeType( 'application/vnd.google-apps.spreadsheet' );
$file = $driveService->files->create( $file );

$feedbackMessage = sprintf( 'Created spreadsheet via DRIVE API with Id: %s', $file->id );
但是障碍!!这是一个“服务帐户”。它在驱动器web前端看不到的某种“秘密”位置创建和修改文件

发生了什么 我有一个用户(例如称之为
alice@gmail.com
)而该用户就是创建“服务帐户”的用户。凭证文件包含某种“虚构的电子邮件地址”,这或多或少让人感到困惑:
alice@my-尼斯超级项目.iam.gserviceaccount.com

.json大致类似于以下内容:

{
  "type": "service_account",
  "project_id": "my-nice-super-project",
  "private_key_id": "7777777777777788888888888888899999999999",
  "private_key": "-----BEGIN PRIVATE KEY-----\nxxx[...]xxx==\n-----END PRIVATE KEY-----\n",
  "client_email": "alice@my-nice-super-project.iam.gserviceaccount.com",
  "client_id": "123456789123456789123",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/alice%40my-nice-super-project.iam.gserviceaccount.com"
}
发生的情况是:

  • 如果我使用
    alice@gmail.com
    并且我手动创建电子表格文件
    Hello-1
    ,然后我无法从应用程序中读取它
  • 如果我以
    alice@gmail.com
    并将其共享给
    alice@my-nice super project.iam.gserviceaccount.com
    ,然后我就可以从应用程序中读取文件了。但是我不能从应用程序中删除它
  • 如果我从应用程序创建文件
    Hello-2
    ,它在
    alice@gmail.com
    web前端
  • 即使服务帐户是从
    alice@gmail.com
    它作为一个完全分离的存储器工作,来自“人类爱丽丝”和“机器人爱丽丝”的文件被视为来自不同的用户

    我需要什么 我想要的是应用程序可以读/写
    alice@gmail.com
    无需提示输入OAuth权限

    因此,要明确的是:我不希望我的PHP web应用程序能够“在征得任何人同意的情况下编辑任何人的驱动器”,但我希望的是“任何人都可以编辑Alice的驱动器”

    背后的原因是,我们已经拥有Alice帐户,它就像某些文档的“中央存储”

    公司中的多个代理必须能够通过应用程序编辑内容,只有老板才能通过Google Drive网站登录。代理没有Alice密码,因此无法通过OAuth获得同意。但是该公司拥有Alice帐户,因此我们可以在那里输入并创建API密钥,然后在服务器中设置它们

    我被困在哪里 我可以通过服务帐户使软件正常工作。但这并不是我想要的:我想要软件在“Alice的文档”上运行,而不是在“Alice服务帐户的文档”上运行,因为它们似乎生活在不同的世界中

    我不知道如何初始化

    $service = new \Google_Service_Drive( $client );
    
    因此,它可以在未经OAuth同意的情况下处理Alice的文件。

    当您使用服务帐户时,如果您有,您可以使用,这样您的服务帐户
    alice@my-nice super project.iam.gserviceaccount.com
    将能够模拟您想要的任何用户,在这种情况下,您的
    alice@gmail.com

    这将帮助您在
    alice@gmail.com
    使用您已有的代码驾驶。您只需修改代码的这一部分:

    私有函数getClient(字符串$scopes):\Google\u Client
    {
    //添加这行代码
    //要“模拟”的用户
    $user=”alice@gmail.com"
    $client=new\Google_client();
    $client->setApplicationName('My nice application name');
    $client->setAuthConfig($this->getSecretPath());
    $client->setScopes($scopes);
    $client->setAccessType('offline');
    //添加这行代码
    $client->setSubject($user);
    返回$client;
    }
    
    您可以查看有关PHP的Google API客户端库的更多信息。

    • 您想在
      Google驱动器中写入和读取文件alice@gmail.com
      使用服务帐户
    • 您希望以
      alice@gmail.com
      使用服务帐户
    • 您希望使用浏览器查看文件
    为了实现上述情况,我想提出以下方法。请把这看作是几个可能的答案之一

    方法:
  • alice@gmail.com
    并与服务帐户共享文件夹
  • 当具有服务帐户的应用程序在共享文件夹中创建新文件时,将文件的所有者更改为
    alice@gmail.com
    并与服务帐户共享
  • 通过上述方法,应用程序可以写入和读取
    alice@gmail.com
    alice@gmail.com
    可以通过浏览器查看自己帐户中的文件

    注:
    • alice@gmail.com
      与服务帐户的驱动器不同。并且浏览器无法直接看到服务帐户的驱动器。因此,在这种方法中,使用了份额
    参考:

    尽管我不确定是否能正确理解您的目标,例如,在
    alice@gmail.com
    并与服务帐户共享文件夹?当应用程序在共享文件夹中创建新文件时,如何更改ow