403 ошибки для Gdrive API V3 при переключении между несколькими учетными записями - PullRequest
0 голосов
/ 04 июля 2018

Я ищу решение, которое помогло бы пользователям обойти запрет 403 при переключении учетных записей и щелкнуть webViewLink или webContentLink, чтобы загрузить файл.

Мы используем Gdrive API V3 (узел) с учетной записью службы Google. Мы собираем файлы, чтобы наша команда легко к ним обращалась. Сервер заполняет контент, а затем пользователи получают к нему доступ по ссылке.

Итак, проблема в следующем:

  • Пользователь входит в систему
  • Они делают свое дело, загружают некоторый контент, без проблем, потому что они вошли в свою рабочую учетную запись
  • Пользователь идет, чтобы проверить свою личную электронную почту или получить что-то с диска, чтобы они переключили учетные записи Google
  • Затем пользователь снова пытается получить доступ к контенту (мы используем webContentLink/webViewLink), и он получает 403

Это совершенно понятно, Google не знает, что это тот же человек, который пытается получить доступ к контенту.

Несколько решений высокого уровня, о которых я подумал:

  1. Когда ссылка нажата, добавьте разрешение, позволяющее кому-либо ее просматривать, и задайте срок ее действия в течение n секунд (это может быть невозможно при использовании permissions.create)
  2. Каким-то образом сохраните правильную аутентификацию и используйте ее, когда нажимаете на ссылку (понимая, что я не уверен, как браузер знает, какой токен отправить)
  3. Включите «Любой, у кого есть ссылка, может просматривать» (это проблематично по соображениям безопасности, если кто-то покинул компанию и все еще имел ссылку или кто-то наткнулся на нее)
  4. Добавить аутентификацию на клиент с учетными данными учетной записи службы
  5. Экспорт и загрузка этих файлов непосредственно на сервер (возможно с .key и другими странными форматами?)

Многие файлы, к которым необходимо получить доступ, - это .key и .mov среди других, таких как .ppt и файлы / папки на диске.

Итак, два (иш) вопроса здесь:

  1. Как лучше всего решить эту проблему? Можно ли использовать библиотеку nodejs-client для программной загрузки всех этих типов файлов? Может ли это решить вопрос делегирования полномочий на уровне домена?

  2. Можно ли указать, какие учетные данные используются на стороне клиента, даже если сервер выполняет всю начальную аутентификацию?

Спасибо за любую помощь и понимание здесь! Это полная боль!

1 Ответ

0 голосов
/ 04 июля 2018

Вот решение для быстрого исправления:

403 ошибка прямой ссылки Google Диска из-за нескольких учетных записей, зарегистрированных в

Вы можете использовать drive.google.com/u/1/uc?id=DOCID или drive.google.com/a/mycorporatedomain.com/uc?id=DOCID

Однако не полагайтесь на то, что эти URL не изменятся в будущем.

Вот более надежное решение, если вы используете серверный API:

Идея состоит в том, чтобы перехватить ссылку, по которой щелкают, получить необходимые метаданные (ID, имя файла, mimeType) и запросить файл у Google через сервер Node. Вы можете указать ответ в виде потока и отправить этот поток для открытия через встроенное вложение.

Эти две ссылки помогут:

узел / экспресс Принудительный браузер для загрузки файла с произвольным именем

Как отправить файл с удаленного URL-адреса в виде ответа GET в приложении Node.js Express?

В контексте приложения Express, вот как это может выглядеть:

// I'm using an async function here, but it may not be best practice.
app.get('/download', async function(req, res, next) {
  // get the metadata from req.query
  const fileId = req.query.id;
  const filename = req.query.name;
  const mimeType = req.query.mimeType;
  const inlineFilename = `inline;filename=${ filename }`;

  // Set the Content-Disposition to specify a filename
  // Set the Content-Type to accept a stream, because that's what we want back from google.
  res.set("Content-Disposition", inlineFilename);
  res.set("Content-Type", "application/octet-stream");

  // This returns a data stream from google so that we are able to pipe the result.
  const fileStream = await downloadFile(fileId);

  // Pipe the stream to the res. This sends the file stream to the client to be downloaded
  fileStream.pipe(res);

});

downloadFile может выглядеть примерно так (с помощью google-api-nodejs-client ):

downloadFile: async function(fileId) {
  try {      
    const response = await drive.files.get(
      {fileId, alt: 'media'},
      {responseType: 'stream'}
    );

    return response.data
  } catch (error) {
    console.error(error);
 }

}

...