我正在尝试让我的网络应用程序使用专用的电子邮件帐户通过API将文件上传到谷歌驱动器。问题在于它一直要求潜在用户验证我为其准备的帐户,这正是我试图阻止其需要的。
我遇到的任何解决方案都指示我使用刷新令牌以确保帐户保持授权。这仍然存在这样的问题:在第一次使用时,用户必须验证所述帐户。使用刷新令牌在本地保存访问令牌不起作用,因为它仍然强制新用户进行身份验证。 下面的代码段显示了用于验证的代码。
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_Exception,声明客户端未经授权使用此方法检索访问令牌。我不确定哪里出错了。
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;
}
- >编辑: 如果你投票,我想知道为什么这样我可以改善我当前和未来的问题。
答案 0 :(得分:1)
您目前正在使用Oauth2进行身份验证。 Oauth2允许您请求用户访问他们的谷歌驱动器帐户。假设他们授予您访问权限,您将获得一个访问令牌,允许您访问他们的数据一小时。如果您请求离线访问,您将获得一个刷新令牌,当访问令牌到期时,您可以使用该令牌来请求新的访问令牌。
在您的情况下,因为您试图访问自己的驱动器帐户,我总是认为您需要使用服务帐户。服务帐户已获得批准,您可以在其上共享您的Google云端硬盘帐户中的文件夹,只要您不删除权限,它就可以访问该驱动器帐户。我有一篇关于服务帐户如何运作的帖子Google developer for beginners service account
示例:
// 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();
}
}
代码从我的示例项目serviceaccount.php
中删除用法:
require_once __DIR__ . '/vendor/autoload.php';
session_start();
require_once __DIR__ . '/ServiceAccount.php';
$client = getGoogleClient();
$service = new Google_Service_Drive($client);
然后,您的所有请求都会使用$service