使用 JavaScript 从客户端浏览器上传到 Google Cloud Storage

Posted

技术标签:

【中文标题】使用 JavaScript 从客户端浏览器上传到 Google Cloud Storage【英文标题】:Upload from Client Browser to Google Cloud Storage Using JavaScript 【发布时间】:2016-06-15 06:50:35 【问题描述】:

我正在使用 Google 云存储。要上传到云存储,我研究了不同的方法。我发现最常见的方法是将文件发送到服务器,然后从那里发送到 Google Cloud 存储。

我想将文件直接从用户的网络浏览器移动到 Google Cloud Storage。我找不到任何与此相关的教程。我已经阅读了适用于 javascript 的 Google API Client SDK。

通过 Google API 参考,它指出可以使用 HTTP 请求传输文件。但我对如何使用API client library for JavaScript.

感到困惑

这里的人需要共享一些代码。但是我没有写任何代码,我没能找到一种方法来完成这项工作。

【问题讨论】:

通常的方法是使用 firebase 存储 API 进行“put”调用。参考在这里:firebase.google.com/docs/storage/web/upload-files 这是一个坏主意,因为它基本上允许任何人上传任何内容,而通过服务器让您有机会监管和验证提交并隐藏您的 API 密钥。 我不确定您是否希望用户在不进行身份验证的情况下执行此操作。这是您所追求的,还是您正在寻找能够执行此操作的经过身份验证的用户? 【参考方案1】:

编辑 1:未经测试的示例代码

所以我对此非常感兴趣,并有几分钟时间整理了一些代码。我决定构建一个小型 Express 服务器来获取访问令牌,但仍然从客户端进行上传。我使用fetch 代替客户端库进行上传。

我没有 Google 云帐户,因此没有对此进行测试,因此我无法确认它是否有效,但我不明白为什么它不应该。代码是on my GitHub here。

在尝试运行它之前,请通读它并进行必要的更改。最值得注意的是,您需要指定私钥文件的位置,并确保它在那里,并且您需要在index.html 中设置存储桶名称。

编辑结束 1

免责声明:我只使用过 Node.js Google 客户端库来发送电子邮件,但我认为我对 Google 的 API 有基本的了解。

为了使用任何 Google 服务,我们需要访问令牌来验证我们的身份;但是,由于我们希望允许任何用户上传到我们自己的 Cloud Storage 存储桶,因此我们不需要通过标准的 OAuth 流程。

Google 提供了他们所谓的服务帐户,我们使用该帐户来识别我们自己的应用程序访问我们自己的资源的实例。而在标准 OAuth 流程中,我们需要向服务标识我们的应用程序,让用户同意使用我们的应用程序(从而授予我们权限),获取该特定用户的访问令牌,然后向服务发出请求;使用服务帐户,我们可以跳过用户同意过程,因为从某种意义上说,我们是我们自己的用户。使用服务帐户使我们能够简单地使用从 Google API 控制台生成的凭据来生成 JWT(JSON Web 令牌),然后我们使用它来获取访问令牌,我们使用它来向云存储服务发出请求。有关此过程的 Google 指南,请参阅 here。

过去,我使用像this one 这样的包来生成 JWT,但我找不到任何用于编码 JWT 的客户端库;主要是因为它们几乎完全在服务器上生成。但是,我发现this tutorial,粗略一看,似乎足以编写我们自己的编码算法。

我想在此指出,打开应用程序以允许公众免费访问您的 Google 资源可能会在未来证明对您或您的组织有害,我相信您已经考虑过。这是一个重大的安全风险,这就是为什么到目前为止你看到的所有教程都实现了两次连续上传。

如果是我,我至少会在我的服务器上完成身份验证过程的第一部分:当用户准备上传时,我会向我的服务器发送一个请求,以使用我的服务帐户的凭据,然后我会向每个用户发送我的服务器生成的新访问令牌。这样,我在外部世界和我的 Google 帐户之间增加了一层安全性,因为身份验证的负担在于我的服务器,并且只有上传由客户端完成。

无论如何,一旦我们有了访问令牌,我们就可以利用CORS feature that Google provides 将文件上传到我们的存储桶。此功能允许我们使用标准的XHR 2 请求来使用 Google 的服务,并且本质上旨在用于代替JavaScript client library。我宁愿在客户端库上使用 CORS 功能,只是因为我认为它更简单一些,并且在实现上更灵活一些。 (我还没有对此进行测试,但我认为fetch 在这里和XHR 2 一样有效。)。

从这里,我们需要从用户那里获取文件,以及我们想要从他们那里获得的关于文件的任何信息(读取:文件名),然后向POST 发出https://www.googleapis.com/upload/storage/v1/b/<BUCKET_NAME_HERE>/o 请求(替换为您的存储桶的名称,当然)根据CORS feature page 的 Making authenticated requests 部分以及您在正文/查询字符串中的任何其他参数添加到 URL 的访问令牌希望包括,根据Cloud Storage API documentation on inserting an object。云存储服务的 API 列表可以在 here 找到以供参考。

因为我以前从未这样做过,而且我没有能力对此进行测试,所以我没有任何示例代码可以包含在我的答案中,但我希望我的帖子足够清楚,可以将从这里开始,代码应该相对简单。

为了澄清事实,我一直觉得 OAuth 非常令人困惑,并且由于害怕它的未知性,我通常会回避使用它。但是,我想我终于掌握了它,尤其是在这篇文章之后,所以我迫不及待地想抽出一个小时来玩它。

如果我说的任何内容不清楚或连贯,请告诉我。

【讨论】:

以上是关于使用 JavaScript 从客户端浏览器上传到 Google Cloud Storage的主要内容,如果未能解决你的问题,请参考以下文章

从客户端浏览器直接上传 Amazon S3 文件 - 私钥泄露

上传/下载之前/之后的客户端(javascript/jQuery)文件操作

如何在不传输整个文件的情况下限制使用 JavaScript(或 Java)上传的文件的大小?

文件上传正在使用 Postman,但不适用于从浏览器运行的 Javascript

我可以将图像直接从客户端浏览器上传到 CloudFront 吗?

我可以将多张图片上传到浏览器并使用 Javascript 将其压缩到一个文件中吗?