在多个帐户之间切换时 Gdrive API V3 出现 403 错误
403 errors for Gdrive API V3 when switching between multiple accounts
我正在寻找一种解决方案,以帮助用户在切换帐户并单击 webViewLink
或 webContentLink
下载文件时绕过 403 forbidden。
我们使用 Gdrive API V3(节点)和 google 服务帐户。我们正在汇总文件,以便我们的团队轻松访问。服务器填充内容,然后用户通过 link.
访问它们
所以问题是这样的:
- 用户登录
- 他们做他们的事,下载一些内容,没有问题,因为他们登录到他们的工作帐户
- 用户去检查他们的个人电子邮件,或者从云端硬盘中获取一些东西,所以他们切换 google 个帐户
- 用户然后再次尝试访问内容(我们正在使用
webContentLink/webViewLink
),他们收到 403
这完全可以理解,Google不知道是同一个人试图访问内容。
我想到的几个高级解决方案:
- 点击link时,添加允许任何人查看的权限,并设置n秒内过期(permissions.create可能不行)
- 以某种方式保存正确的身份验证并在您单击 link 时使用它(意识到我不确定浏览器如何知道要发送哪个令牌)
- 打开 "Anyone with link can view"(出于安全原因,这是有问题的,以防万一有人离开公司但仍然拥有 link 或者有人无意中发现了它)
- 使用服务帐户凭据向客户端添加身份验证
- 直接在服务器上导出和下载这些文件(可能是 .key 和其他奇怪的格式?)
许多需要访问的文件是 .key
和 .mov
,其中 .ppt
和驱动器 files/folders。
这里有两个(大概)问题:
解决此问题的最佳方法是什么?是否可以使用 nodejs-client 库以编程方式下载所有这些文件类型?这是委托全域权限可能解决的问题吗?
是否可以指定客户端使用哪些凭据,即使服务器正在执行所有初始身份验证?
在此感谢您的帮助和见解!这真是太痛苦了!
这是快速解决方案:
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);
}
}
我正在寻找一种解决方案,以帮助用户在切换帐户并单击 webViewLink
或 webContentLink
下载文件时绕过 403 forbidden。
我们使用 Gdrive API V3(节点)和 google 服务帐户。我们正在汇总文件,以便我们的团队轻松访问。服务器填充内容,然后用户通过 link.
访问它们所以问题是这样的:
- 用户登录
- 他们做他们的事,下载一些内容,没有问题,因为他们登录到他们的工作帐户
- 用户去检查他们的个人电子邮件,或者从云端硬盘中获取一些东西,所以他们切换 google 个帐户
- 用户然后再次尝试访问内容(我们正在使用
webContentLink/webViewLink
),他们收到 403
这完全可以理解,Google不知道是同一个人试图访问内容。
我想到的几个高级解决方案:
- 点击link时,添加允许任何人查看的权限,并设置n秒内过期(permissions.create可能不行)
- 以某种方式保存正确的身份验证并在您单击 link 时使用它(意识到我不确定浏览器如何知道要发送哪个令牌)
- 打开 "Anyone with link can view"(出于安全原因,这是有问题的,以防万一有人离开公司但仍然拥有 link 或者有人无意中发现了它)
- 使用服务帐户凭据向客户端添加身份验证
- 直接在服务器上导出和下载这些文件(可能是 .key 和其他奇怪的格式?)
许多需要访问的文件是 .key
和 .mov
,其中 .ppt
和驱动器 files/folders。
这里有两个(大概)问题:
解决此问题的最佳方法是什么?是否可以使用 nodejs-client 库以编程方式下载所有这些文件类型?这是委托全域权限可能解决的问题吗?
是否可以指定客户端使用哪些凭据,即使服务器正在执行所有初始身份验证?
在此感谢您的帮助和见解!这真是太痛苦了!
这是快速解决方案:
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);
}
}