如何使用 API 密钥从 PHP 通过 google/apiclient 驱动 Google 驱动器 API
How to use the API Key for Google Drive API from PHP via the google/apiclient
我希望我的 PHP 网络应用程序在特定的 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
来创建,其中 returns 是一个已初始化的 \Google_Client
对象,后者又将 credentials.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 );
但是手残!!这是作为 "Service Account" 工作的。它在某种 "secret" 的地方创建和修改文件,这在云端硬盘 Web 前端是不可见的。
会发生什么
我有一个用户(例如 alice@gmail.com
),这个用户就是创建 "Service account" 的用户。凭据文件包含某种 "ficticious email address" 或多或少类似的内容:alice@my-nice-super-project.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
登录到 google 驱动器(使用浏览器)并手动创建电子表格文件 Hello-1
然后我无法从应用程序中读取它。
- 如果我从登录为
alice@gmail.com
的网站手动共享文件 Hello-1
并将其共享到 alice@my-nice-super-project.iam.gserviceaccount.com
,那么我可以从应用程序读取文件。但是我无法从应用程序中删除它。
- 如果我从应用程序创建文件
Hello-2
,它在 alice@gmail.com
网络前端是不可见的。
似乎即使服务帐户是从 alice@gmail.com
创建的,它也作为一个完全独立的存储工作,来自 "human Alice" 和 "robot Alice" 的文件被视为来自不同的存储用户。
我需要什么
我想要的是应用程序可以 read/write alice@gmail.com
的文件而不提示 OAuth 权限。
所以,要明确一点:我不希望我的 PHP 网络应用程序能够 "edit anyone's Drive with his consent",但我想要的是 "anyone can edit Alice's Drive".
背后的原因是我们已经拥有了爱丽丝账户,它就像一些文件的"central storage"。
公司中的多个代理必须能够通过应用程序编辑内容,只有老板才能通过 Google Drive 站点登录。代理没有 Alice 密码,因此他们无法通过 OAuth 同意。但该公司拥有 Alice 帐户,因此我们可以进入那里并创建 API 密钥,并将它们设置在服务器中。
我卡在哪里
我可以通过服务帐户设法使软件运行。但这不是我想要的:我希望该软件能够运行 "on Alice's documents",而不是在 "Alice Service Account's documents" 上运行,因为它们似乎生活在不同的世界中。
我不知道如何初始化
$service = new \Google_Service_Drive( $client );
所以它可以在没有 OAuth 同意的情况下使用 Alice 的文件。
当您使用服务帐户并且您有G Suite Account, you can use Domain-Wide Delegation of Authority ,这样您的服务帐户 alice@my-nice-super-project.iam.gserviceaccount.com
将能够模拟您想要的任何用户,在本例中是您的 alice@gmail.com
.
这将帮助您使用已有的代码在 alice@gmail.com
驱动器中创建文件。您只需要修改这部分代码:
private function getClient( string $scopes ) : \Google_Client
{
// Add this line of code
// User you want to "impersonate"
$user = "alice@gmail.com"
$client = new \Google_Client();
$client->setApplicationName( 'My nice application name.' );
$client->setAuthConfig( $this->getSecretPath() );
$client->setScopes( $scopes );
$client->setAccessType( 'offline' );
// Add this line of code
$client->setSubject( $user );
return $client;
}
HERE 您可以查看有关 PHP.
的 Google API 客户端库的更多信息
- 您想使用服务帐户写入和读取
alice@gmail.com
的 Google 驱动器中的文件。
- 您想使用服务帐户写入和读取
alice@gmail.com
的文件。
- 您想用浏览器查看文件。
为了实现上述情况,我想提出以下方法。请将此视为几个可能的答案之一。
方法:
- 在
alice@gmail.com
的驱动器中创建一个文件夹并与服务帐户共享该文件夹。
- 当使用服务帐户的应用程序在共享文件夹中创建新文件时,将文件的所有者更改为
alice@gmail.com
并与服务帐户共享。
通过以上方法,应用程序可以写入和读取alice@gmail.com
的文件,并且alice@gmail.com
可以通过浏览器查看自己帐户中的文件。
注:
alice@gmail.com
的Drive与服务账号的Drive不同。并且浏览器无法直接看到服务帐户的Drive。所以在这个方法中,使用了share。
参考:
我希望我的 PHP 网络应用程序在特定的 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
来创建,其中 returns 是一个已初始化的 \Google_Client
对象,后者又将 credentials.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 );
但是手残!!这是作为 "Service Account" 工作的。它在某种 "secret" 的地方创建和修改文件,这在云端硬盘 Web 前端是不可见的。
会发生什么
我有一个用户(例如 alice@gmail.com
),这个用户就是创建 "Service account" 的用户。凭据文件包含某种 "ficticious email address" 或多或少类似的内容:alice@my-nice-super-project.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
登录到 google 驱动器(使用浏览器)并手动创建电子表格文件Hello-1
然后我无法从应用程序中读取它。 - 如果我从登录为
alice@gmail.com
的网站手动共享文件Hello-1
并将其共享到alice@my-nice-super-project.iam.gserviceaccount.com
,那么我可以从应用程序读取文件。但是我无法从应用程序中删除它。 - 如果我从应用程序创建文件
Hello-2
,它在alice@gmail.com
网络前端是不可见的。
似乎即使服务帐户是从 alice@gmail.com
创建的,它也作为一个完全独立的存储工作,来自 "human Alice" 和 "robot Alice" 的文件被视为来自不同的存储用户。
我需要什么
我想要的是应用程序可以 read/write alice@gmail.com
的文件而不提示 OAuth 权限。
所以,要明确一点:我不希望我的 PHP 网络应用程序能够 "edit anyone's Drive with his consent",但我想要的是 "anyone can edit Alice's Drive".
背后的原因是我们已经拥有了爱丽丝账户,它就像一些文件的"central storage"。
公司中的多个代理必须能够通过应用程序编辑内容,只有老板才能通过 Google Drive 站点登录。代理没有 Alice 密码,因此他们无法通过 OAuth 同意。但该公司拥有 Alice 帐户,因此我们可以进入那里并创建 API 密钥,并将它们设置在服务器中。
我卡在哪里
我可以通过服务帐户设法使软件运行。但这不是我想要的:我希望该软件能够运行 "on Alice's documents",而不是在 "Alice Service Account's documents" 上运行,因为它们似乎生活在不同的世界中。
我不知道如何初始化
$service = new \Google_Service_Drive( $client );
所以它可以在没有 OAuth 同意的情况下使用 Alice 的文件。
当您使用服务帐户并且您有G Suite Account, you can use Domain-Wide Delegation of Authority ,这样您的服务帐户 alice@my-nice-super-project.iam.gserviceaccount.com
将能够模拟您想要的任何用户,在本例中是您的 alice@gmail.com
.
这将帮助您使用已有的代码在 alice@gmail.com
驱动器中创建文件。您只需要修改这部分代码:
private function getClient( string $scopes ) : \Google_Client
{
// Add this line of code
// User you want to "impersonate"
$user = "alice@gmail.com"
$client = new \Google_Client();
$client->setApplicationName( 'My nice application name.' );
$client->setAuthConfig( $this->getSecretPath() );
$client->setScopes( $scopes );
$client->setAccessType( 'offline' );
// Add this line of code
$client->setSubject( $user );
return $client;
}
HERE 您可以查看有关 PHP.
的 Google API 客户端库的更多信息- 您想使用服务帐户写入和读取
alice@gmail.com
的 Google 驱动器中的文件。 - 您想使用服务帐户写入和读取
alice@gmail.com
的文件。 - 您想用浏览器查看文件。
为了实现上述情况,我想提出以下方法。请将此视为几个可能的答案之一。
方法:
- 在
alice@gmail.com
的驱动器中创建一个文件夹并与服务帐户共享该文件夹。 - 当使用服务帐户的应用程序在共享文件夹中创建新文件时,将文件的所有者更改为
alice@gmail.com
并与服务帐户共享。
通过以上方法,应用程序可以写入和读取alice@gmail.com
的文件,并且alice@gmail.com
可以通过浏览器查看自己帐户中的文件。
注:
alice@gmail.com
的Drive与服务账号的Drive不同。并且浏览器无法直接看到服务帐户的Drive。所以在这个方法中,使用了share。