Не удается выполнить экспорт файла Google Drive API в конечной точке при аутентификации по ключу API?
Что-нибудь изменилось в последнее время с API Google Drive и, в частности, с функцией " Экспорт", что может привести к сбою при использовании доступа к API-ключу после 27 марта 2018 года?
У меня есть служба Windows, которая создает и отправляет ежедневные электронные письма о курсе для образовательной группы. Исходный контент для каждого электронного письма хранится на Google Диске, как Google Doc, так что преподаватели могут легко обновлять содержание курса.
Это работало безупречно в течение прошлого года, но внезапно перестало работать около 27 марта 2018 года. С тех пор я могу получить информацию о файле;
_googleDriveHtmlContent.LoadFile(
fileId
);
Но не содержание. Когда я Export
файл в формате HTML, я сразу получаю DownloadStatus.Failed
от ProgressChanged
обработчик;
var request = _driveService.Files.Export(
fileId,
"text/html"
);
Я использую ключи API для безопасности, а не OAuth, поскольку это сервис без пользовательского интерфейса. Для этого мне нужно пометить папки с файлами как общедоступные - в частности, я использую "Доступно для всех со ссылкой". Это работает отлично.
Я обновил до последних библиотек API v3 через NuGet, без изменений в поведении.
Используя Google Explorer Explorer, я вижу похожее поведение.
Я могу получить свой файл успешно, используя API Explorer с get
конечная точка. https://developers.google.com/drive/v3/reference/files/get
- FILEID
1AIuGhzXsNuhhi0PMA1pblh0l5CCDaa1nPj8t_dasi_c
- Аутентификация: ключ API (используется "демонстрационный ключ API")
Но с export
конечная точка, я получаю внутреннюю ошибку (500)- https://developers.google.com/drive/v3/reference/files/export
- FILEID
1AIuGhzXsNuhhi0PMA1pblh0l5CCDaa1nPj8t_dasi_c
- MIMETYPE:
text/html
- Аутентификация: ключ API (используется "демонстрационный ключ API")
Изменив Аутентификацию в API Explorer на OAuth 2.0 и подтвердив доступ, вы получите успешный результат 200 с файлом HTML. Однако я не могу этого сделать, так как я получаю доступ к API через сервис без пользовательского интерфейса.
1 ответ
Что-нибудь изменилось в последнее время с API Google Drive и, в частности, с функцией "Экспорт", что может привести к сбою при использовании доступа к API-ключу после 27 марта 2018 года?
Это возможно, но, скорее всего, это скрытое изменение, о котором вы не получите никакого официального слова. Не так давно я видел, как кто-то отправлял похожий вопрос, он использовал API-ключ для обновления листа Google, и он внезапно перестал работать.
ИМО, если Google изменил это, вероятно, это хорошая вещь. Ключи API предназначены для доступа к публичным данным. Установка публичного документа - это действительно плохая идея, если кому-то удастся найти идентификатор файла вашего документа, то он сможет обновить ваш документ.
Предложение:
То, что вы должны использовать, это служебная учетная запись. Служебные учетные записи являются фиктивными пользователями, создавая учетные данные служебной учетной записи на консоли разработчика Google, а затем, взяв адрес электронной почты служебной учетной записи, вы можете поделиться файлом на Google Диске с учетной записью службы, предоставив ей доступ к указанному файлу без необходимости публикации файла.
Вы не указали, какой язык вы используете, но вы сказали, что делаете службу 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.
После того как вы предоставили доступ к файлу своей учетной записи службы, он сможет получить доступ к файлу, когда в этом будет необходимость, аутентификация не требуется, поскольку вы предварительно авторизовали его, предоставив ему доступ к файлу.