0

Google Drive API尤其是导出功能最近是否发生了任何变化,这会导致它在 2018 年 3 月 27 日之后使用 API 密钥访问时失败?

我有一个 Windows 服务,它为教育组创建和发送每日课程电子邮件。每封电子邮件的源内容都以 Google Doc 的形式存储在 Google Drive 中,以便教师可以轻松更新课程内容。

这在过去一年中一直运行良好,但在 2018 年 3 月 27 日左右突然停止工作。从那时起,我可以检索文件详细信息;

    _googleDriveHtmlContent.LoadFile(
        fileId
        );

但不是内容。当我Export将文件作为 HTML 文件时,我立即DownloadStatus.FailedProgressChanged处理程序中得到一个;

    var request = _driveService.Files.Export(
        fileId, 
        "text/html"
        );

我使用 API 密钥来保证安全,而不是 OAuth,因为它是一种无 UI 服务。为此,我需要将文件夹标记为可公开访问 - 具体来说,我使用的是“所有人都可以访问,带有链接”。这一直很好。

我已通过 NuGet 更新到最新的 API v3 库,但行为没有任何变化。

使用 Google 的 API Explorer,我看到了类似的行为。

get我可以使用带有端点 的 API Explorer 成功检索我的文件。https://developers.google.com/drive/v3/reference/files/get

  • 文件标识1AIuGhzXsNuhhi0PMA1pblh0l5CCDaa1nPj8t_dasi_c
  • 身份验证:API 密钥(使用“演示 API 密钥”)

但是对于export端点,我得到一个内部错误(500) - https://developers.google.com/drive/v3/reference/files/export

  • 文件标识1AIuGhzXsNuhhi0PMA1pblh0l5CCDaa1nPj8t_dasi_c
  • 哑剧类型:text/html
  • 身份验证:API 密钥(使用“演示 API 密钥”)

将 API Explorer 中的身份验证更改为 OAuth 2.0,并批准访问,然后返回成功的 200 结果以及文件 HTML。但是我无法做到这一点,因为我通过无 UI 服务访问 API。

4

1 回答 1

1

Google Drive API 尤其是导出功能最近是否发生了任何变化,这会导致它在 2018 年 3 月 27 日之后使用 API 密钥访问时失败?

它是可能的,但很可能是你不会得到任何官方消息的隐形改变。不久前,我看到有人发布了一个类似的问题,他们正在使用 API 密钥更新 Google 表格,但它突然停止工作。

IMO 如果谷歌改变了这可能是一件好事。API 密钥用于访问公共数据。如果有人确实设法找到您的文档的文件 ID,然后他们就可以更新您的文档,那么将文档设置为公开是一个非常糟糕的主意。

建议:

您应该使用的是服务帐户。服务帐户是虚拟用户,通过在 Google 开发人员控制台上创建服务帐户凭据,然后获取服务帐户电子邮件地址,您可以与服务帐户共享 Google Drive 上的文件,授予其访问所述文件的权限,而无需公开文件。

您尚未指定您使用的语言,但您说您正在制作 Windows 服务,所以我假设您使用的是 .net。这是使用 Google .net 客户端库进行服务帐户身份验证的示例。

 public static DriveService AuthenticateServiceAccount(string serviceAccountEmail, string serviceAccountCredentialFilePath, string[] scopes)
    {
        try
        {
            if (string.IsNullOrEmpty(serviceAccountCredentialFilePath))
                throw new Exception("Path to the service account credentials file is required.");
            if (!File.Exists(serviceAccountCredentialFilePath))
                throw new Exception("The service account credentials file does not exist at: " + serviceAccountCredentialFilePath);
            if (string.IsNullOrEmpty(serviceAccountEmail))
                throw new Exception("ServiceAccountEmail is required.");                

            // For Json file
            if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".json")
            {
                GoogleCredential credential;
                using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
                {
                    credential = GoogleCredential.FromStream(stream)
                         .CreateScoped(scopes);
                }

                // Create the  Analytics service.
                return new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive Service account Authentication Sample",
                });
            }
            else if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".p12")
            {   // If its a P12 file

                var certificate = new X509Certificate2(serviceAccountCredentialFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
                var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
                {
                    Scopes = scopes
                }.FromCertificate(certificate));

                // Create the  Drive service.
                return new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive Authentication Sample",
                });
            }
            else
            {
                throw new Exception("Unsupported Service accounts credentials.");
            }

        }
        catch (Exception ex)
        {                
            throw new Exception("CreateServiceAccountDriveFailed", ex);
        }
    }
}

serviceaccount.cs中提取的代码。假设您已经在使用 Google .net 客户端库,则此方法返回的服务将与您使用 api 密钥使用的驱动器服务相同。

一旦您授予您的服务帐户对文件的访问权限,它就可以在需要时访问该文件,因为您已通过与它共享文件来对其进行预授权,因此无需进行身份验证。

于 2018-04-01T11:56:14.297 回答