繁体   English   中英

如何通过服务帐户使用 Google Drive PHP Api

[英]How to use Google Drive PHP Api with service account

我已经编写了一系列函数来在 Google Drive 中执行操作,例如复制文件夹、复制文档、获取文档内容等。当我使用 OAuth 以特定用户身份进行身份验证时,它们都可以工作。 现在我已经切换到服务帐户来验证我的应用程序,并且这些功能不再起作用。 例如,当我尝试复制文档时,出现“找不到文件错误”,指的是我要复制的原始文档。 同样,如果我使用 OAuth,效果很好。 我已按照谷歌示例进行身份验证作为服务帐户,但它似乎不起作用。

这是我使用服务帐户获取客户端的代码:

{

    putenv("GOOGLE_APPLICATION_CREDENTIALS=credentials.json");
    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->setApplicationName('Application Name');
    $client->setScopes($scopes);

    return $client;

}

这是我的副本文件 function

function copyDocument($originId, $name, $parents)

{
    $client = getClient(Google_Service_Drive::DRIVE);
    $service = new Google_Service_Drive($client);
    $origin = $originId;
    $document = new Google_Service_Drive_DriveFile();
    $document->setParents(array($parents));
    $document->setName($name);
    $response = $service->files->copy($origin, $document);
    return $response;
}

这将返回错误:

Fatal error: Uncaught Google\Service\Exception: {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "notFound",
    "message": "File not found: 1TRRohZ1Ok4McyVFJ6OrySG2E4Q32nggakS27hU8QGAs.",
    "locationType": "parameter",
    "location": "fileId"
   }
  ],
  "code": 404,
  "message": "File not found: 1TRRohZ1Ok4McyVFJ6OrySG2E4Q32nggakS27hU8QGAs."
 }
}

同样,如果我将以下内容用作我的 getClient function,那么复制文件夹就可以了。

function getClient($scopes)
{

    $client = new Google_Client();
    $client->setApplicationName('Application Name');
    $client->setScopes($scopes);
    $client->setAuthConfig(__DIR__ . '/credentials.json');
    $client->setAccessType('offline');
    $client->setPrompt('select_account consent');

    // Load previously authorized token from a file, if it exists.
    // The file token.json stores the user's access and refresh tokens, and is
    // created automatically when the authorization flow completes for the first
    // time.
    $tokenPath = 'token.json';
    if (file_exists($tokenPath)) {
        $accessToken = json_decode(file_get_contents($tokenPath), true);
        $client->setAccessToken($accessToken);
    }

    // If there is no previous token or it's expired.
    if ($client->isAccessTokenExpired()) {
        // Refresh the token if possible, else fetch a new one.
        if ($client->getRefreshToken()) {
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
        } else {
            // Request authorization from the user.
            $authUrl = $client->createAuthUrl();
            printf("Open the following link in your browser:\n%s\n", $authUrl);
            print 'Enter verification code: ';
            $authCode = trim(fgets(STDIN));

            // Exchange authorization code for an access token.
            $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
            $client->setAccessToken($accessToken);

            // Check to see if there was an error.
            if (array_key_exists('error', $accessToken)) {
                throw new Exception(join(', ', $accessToken));
            }
        }
        // Save the token to a file.
        if (!file_exists(dirname($tokenPath))) {
            mkdir(dirname($tokenPath), 0700, true);
        }
        file_put_contents($tokenPath, json_encode($client->getAccessToken()));
    }
    
    return $client;

}

作为服务帐户进行身份验证的正确方法是什么???

根据您的问题,我可以理解您的脚本有效。 关于您的问题,我认为在您的情况下,以下几点可能是您当前问题的原因。

  • $origin = $originId; 可能会放在您的 email 帐户的 Google Drive 中。
  • 您可能正在尝试使用服务帐户复制文件。

在这种情况下,服务帐户无法直接查看您 Google Drive 上的文件。 因为服务帐号的 Drive 和你的 Drive 不同。 例如,当您想使用服务帐户复制驱动器上的文件时,请与服务帐户的 email 共享文件。 这样,服务帐户可以看到它并复制文件。 如果您可以与服务帐户共享文件夹,则服务帐户也可以看到文件夹中的文件。

作为附加信息,如果您将使用服务帐户来模拟他们的常规帐户,请检查Iamblichus 评论中提到的域范围委派

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM