Php 如何使用Google Drive API永久授权用户帐户将文件上载到驱动器?
我正试图让我的web应用程序使用专用的电子邮件帐户通过API将文件上传到google drive。问题是,它一直要求潜在用户验证我为它准备的帐户,这正是我试图阻止的需要 我遇到的任何解决方案都指导我使用刷新令牌来确保帐户保持授权。这仍然伴随着一个问题,即在第一次使用时,用户必须对所述帐户进行身份验证。在本地保存带有刷新令牌的访问令牌不起作用,因为它仍然会强制新用户进行身份验证。 下面的代码段显示了用于身份验证的代码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;
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,并发出同样的错误。我还共享了我应该访问的驱动器中的文件夹。让我觉得我缺乏某种许可,或者我的代码出了问题