我正在尝试开发一个应用程序,该应用程序将提供 Linux 文件系统文件夹和 Google Drive 之间的文件夹同步。我遇到的问题是我似乎无法通过以下消息克服 403 错误:
请求的身份验证范围不足
当我填充这些字段/值时,我在 Google“尝试 API”页面这里取得了成功:
'corpa' => 'user'
'includeFilesFromAllDrives' => true
'supportsAllDrives' => true
'spaces' => 'drive'
返回一个对象列表。但是当我在 PHP 中尝试这个时,就像:
$result = $drv->service->files->listFiles( [
'corpa' => 'user'
, 'includeFilesFromAllDrives' => true
, 'supportsAllDrives' => true
, 'spaces' => 'drive'
]) ;
结果是:
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Insufficient Permission",
"domain": "global",
"reason": "insufficientPermissions"
}
],
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
"domain": "googleapis.com",
"metadata": {
"method": "google.apps.drive.v3.DriveFiles.List",
"service": "drive.googleapis.com"
}
}
]
}
}
该页面上有一条评论:
Requires one of the following OAuth scopes:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.appdata
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/drive.metadata
https://www.googleapis.com/auth/drive.metadata.readonly
https://www.googleapis.com/auth/drive.photos.readonly
https://www.googleapis.com/auth/drive.readonly
为了超越这一点,我在创建客户端时实际上选择了这些值的全部(一起)。对于我使用范围没有任何明显的反对,但授权仍然被拒绝。
构建$service对象的代码位于类(DriveStuff)中,如下:
public function GetService($clientSecretFile = null
, $scopes = null
, $useKey = false
, $debug = false
) {
if ($this->DEBUG)
error_log("GetService() called") ;
$this->loginEpoch = time() ; // For automatic login before key expiration (hard limit 1 hour)
if (is_null($this->firstLoginEpoch)) $this->firstLoginEpoch = $this->loginEpoch ;
$this->loginExpires = time() + (60 * 60) ; // Expires in 60 minutes
$this->loginCount++ ;
$pageFile = $this->pathToScript ;
if ($useKey) { // Using API KEY rather than login credentials
$client = new Google_Client() ;
$client->setApplicationName('gDrive stuff');
$client->setDeveloperKey($this->apiKey) ;
}
else { // Standard login to Client services
if (is_null($clientSecretFile))
$clientSecretFile = $this->clientFileJSON ;
if (is_null($clientSecretFile)) {
$clientSecretFile = $this->GetYouTubeControlParameter("CLIENT_SECRET_FILE", $pageFile) ;
$this->clientFileJSON = $clientSecretFile ;
}
if (is_null($scopes))
$scopes = $this->scopes ;
if (is_null($scopes)) {
$scopes = $this->GetYouTubeControlParameter("SCOPES", $pageFile) ;
$this->scopes = $scopes ;
}
if (is_string($scopes))
if (strstr($scopes, ',') > 0)
$scopes = explode(',', $scopes) ;
else
$scopes = [ $scopes ] ;
if ( ! in_array('https://www.googleapis.com/auth/drive', $scopes))
$scopes[] = 'https://www.googleapis.com/auth/drive' ; // Add this service
$this->scopes = $scopes ;
$client = $this->GetAuth($clientSecretFile, $scopes) ;
if ($debug) {
foreach ($client->getScopes() AS $scope)
error_log('Requesed scope: ' . $scope) ;
}
}
$service = new Google_Service_Drive($client) ;
$this->service = $service ;
$this->reLogInFile = $clientSecretFile ; // For automatic login before key expiration (hard limit 1 hour)
$this->reLogInScopes = $scopes ; // For automatic login before key expiration (hard limit 1 hour)
$this->reLogInUseKey = $useKey ; // For automatic login before key expiration (hard limit 1 hour)
return $this->service ;
}
此时的程序代码相当简单:
require_once('DriveRelated/DriveStuff.php') ;
$drv = new DriveStuff($lov, false) ; // True sets debug mode
$service = $drv->GetService(null
, [ 'https://www.googleapis.com/auth/drive'
, 'https://www.googleapis.com/auth/drive.appdata'
, 'https://www.googleapis.com/auth/drive.file'
, 'https://www.googleapis.com/auth/drive.metadata'
, 'https://www.googleapis.com/auth/drive.metadata.readonly'
, 'https://www.googleapis.com/auth/drive.photos.readonly'
, 'https://www.googleapis.com/auth/drive.readonly'
]
, false, true) ;
$result = $drv->service->files->listFiles( [ 'pageSize' => 3000 ],
[
'corpa' => 'user'
, 'includeFilesFromAllDrives' => true
, 'supportsAllDrives' => true
, 'spaces' => 'drive'
]) ;
...日志文件包含:
[03-Aug-2023 20:28:03 America/New_York] Requesed scope: https://www.googleapis.com/auth/drive
[03-Aug-2023 20:28:03 America/New_York] Requesed scope: https://www.googleapis.com/auth/drive.appdata
[03-Aug-2023 20:28:03 America/New_York] Requesed scope: https://www.googleapis.com/auth/drive.file
[03-Aug-2023 20:28:03 America/New_York] Requesed scope: https://www.googleapis.com/auth/drive.metadata
[03-Aug-2023 20:28:03 America/New_York] Requesed scope: https://www.googleapis.com/auth/drive.metadata.readonly
[03-Aug-2023 20:28:03 America/New_York] Requesed scope: https://www.googleapis.com/auth/drive.photos.readonly
[03-Aug-2023 20:28:03 America/New_York] Requesed scope: https://www.googleapis.com/auth/drive.readonly]
[03-Aug-2023 20:28:05 America/New_York] PHP Fatal error: Uncaught Google\Service\Exception: {
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Insufficient Permission",
"domain": "global",
"reason": "insufficientPermissions"
}
],
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
"domain": "googleapis.com",
"metadata": {
"method": "google.apps.drive.v3.DriveFiles.List",
"service": "drive.googleapis.com"
}
}
]
}
}
in /www/cgi-bin/YouTubeRelated/vendor/google/apiclient/src/Http/REST.php:134
Stack trace:
#0 /www/cgi-bin/YouTubeRelated/vendor/google/apiclient/src/Http/REST.php(107): Google\Http\REST::decodeHttpResponse()
#1 [internal function]: Google\Http\REST::doExecute()
#2 /www/cgi-bin/YouTubeRelated/vendor/google/apiclient/src/Task/Runner.php(187): call_user_func_array()
#3 /www/cgi-bin/YouTubeRelated/vendor/google/apiclient/src/Http/REST.php(66): Google\Task\Runner->run()
#4 /www/cgi-bin/YouTubeRelated/vendor/google/apiclient/src/Client.php(922): Google\Http\REST::execute()
#5 /www/cgi-bin/YouTubeRelated/vendor/google/apiclient/src/Service/Resource.php(238): Google\Client->execute()
#6 /www/cgi-bin/YouTubeRelated/vendor/google/apiclient-services/src/Drive/Resource/Files.php(258): Google\Service\Resource->call()
#7 /www/htdocs/gdrive/gdrive-test.php(30): Google\Service\Drive\Resource\Files->listFiles()
#8 {main}
thrown in /www/cgi-bin/YouTubeRelated/vendor/google/apiclient/src/Http/REST.php on line 134
顺便说一句,我尝试了一些范围子集(例如所有只读范围、除只读之外的所有范围等),结果没有任何变化。
我在 YouTube API 方面拥有良好且相当丰富的经验,因此我确信这个问题将会得到克服。现在我正在寻找缺失的部分,以便我可以使用 Google Drive 继续超越这个初学者阶段。
请注意,“requested”一词拼写错误,但这只是一个表面问题。