在多个帐户之间切换时 Gdrive API V3 出现 403 错误

403 errors for Gdrive API V3 when switching between multiple accounts

我正在寻找一种解决方案,以帮助用户在切换帐户并单击 webViewLinkwebContentLink 下载文件时绕过 403 forbidden。

我们使用 Gdrive API V3(节点)和 google 服务帐户。我们正在汇总文件,以便我们的团队轻松访问。服务器填充内容,然后用户通过 link.

访问它们

所以问题是这样的:

这完全可以理解,Google不知道是同一个人试图访问内容。

我想到的几个高级解决方案:

  1. 点击link时,添加允许任何人查看的权限,并设置n秒内过期(permissions.create可能不行)
  2. 以某种方式保存正确的身份验证并在您单击 link 时使用它(意识到我不确定浏览器如何知道要发送哪个令牌)
  3. 打开 "Anyone with link can view"(出于安全原因,这是有问题的,以防万一有人离开公司但仍然拥有 link 或者有人无意中发现了它)
  4. 使用服务帐户凭据向客户端添加身份验证
  5. 直接在服务器上导出和下载这些文件(可能是 .key 和其他奇怪的格式?)

许多需要访问的文件是 .key.mov,其中 .ppt 和驱动器 files/folders。

这里有两个(大概)问题:

  1. 解决此问题的最佳方法是什么?是否可以使用 nodejs-client 库以编程方式下载所有这些文件类型?这是委托全域权限可能解决的问题吗?

  2. 是否可以指定客户端使用哪些凭据,即使服务器正在执行所有初始身份验证?

在此感谢您的帮助和见解!这真是太痛苦了!

这是快速解决方案:

You can use drive.google.com/u/1/uc?id=DOCID or drive.google.com/a/mycorporatedomain.com/uc?id=DOCID

However, do not rely on these URL's not changing in the future.

如果您使用的是服务器端,这里有一个更强大的解决方案API:

想法是劫持 link 被点击,获取您需要的元数据(ID、文件名、mimeType)并通过节点服务器从 google 请求文件。您可以将响应指定为流,并发送该流以通过内联附件打开。

这两个 link 会有所帮助:

node/express Force browser to download file with custom name

How to send a file from remote URL as a GET response in Node.js Express app?

在 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);

});

下载文件看起来像这样(使用 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);
 }

}