【问题标题】:Reverse proxy Google Cloud storage to authenticate requests反向代理 Google Cloud 存储以验证请求
【发布时间】:2018-04-05 08:01:38
【问题描述】:

我想为一些客户提供一个 API 来将文件上传到 Google Cloud Storage。我不希望客户知道实施细节(他们是否将文件上传到谷歌云存储)。这个想法是 API 将对他们发送的请求进行身份验证,并将它们代理到另一个经过身份验证的对 Google Cloud API 的请求。

我不是后端/系统开发人员,所以我不知道解决这个问题的最佳方法是什么。我考虑的两个选项是:

  • 实施反向代理。我对这种方法的主要担忧是这些端点会产生大量流量,而 API 反向代理将无法处理它。
  • 使用来自 Google Cloud Storage 的签名 URL 身份验证机制。用户会要求 API 提供将资源上传到的 URL,然后 API 会将该 URL 发送回用户(包括嵌入的身份验证详细信息)。

有人体验过这种设置吗?你会建议我怎么做?

【问题讨论】:

    标签: authentication google-cloud-storage reverse-proxy


    【解决方案1】:

    我建议使用 App Engine Standard 来设置传输。不幸的是,并非所有受支持的语言都有等效的库。

    在 php 中,这是一个设置从用户到云的直接传输的示例: https://cloud.google.com/appengine/docs/standard/php/googlestorage/user_upload

    这需要 php CloudStorageTools,尽管 CloudStorageTools 存在其他语言,但我不清楚它们是否支持相同的操作。 特别是,这在 Python 中并不明显,但幸运的是,您可以使用 Blobstore API 来做基本相同的事情:https://cloud.google.com/appengine/docs/standard/python/blobstore/

    这种方法的优点是传输不通过 App Engine,既节省了资金又消除了 App Engine 超时问题。

    Java 和 Go 似乎没有可用的等效方法,但我不使用这些语言,所以也许我只是想念它们。当然,如果您正在处理的文件不是太大,您可以将它们上传到 App Engine 并让 App Engine 在您超时之前存储它们。

    如果您要设置直接传输,则无法完全隐藏目标的 URL,因此您的用户可能会告诉您正在使用 Google 存储。我不知道这是否有问题,但如果是这样,您也可以使用存储桶 CNAME 重定向来隐藏它。

    https://cloud.google.com/storage/docs/request-endpoints

    希望这有帮助。

    【讨论】:

      【解决方案2】:

      有一些关于如何使用 Cloud Storage 上传文件的示例。这是example for Java,但也有其他语言(Python、Node、Go、Ruby 等)。

      应用程序使用简单的表单让用户选择本地文件:

      <!-- Rest of the code  -->
      <form method="POST" action="/upload" enctype="multipart/form-data">
          <input type="file" name="file"> <input type="submit">
      </form>
      

      然后将表单发送到/upload servlet:

      @Override
      public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
          final Part filePart = req.getPart("file");
          final String fileName = filePart.getSubmittedFileName();
      
          // Modify access list to allow all users with link to read file
          List<Acl> acls = new ArrayList<>();
          acls.add(Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER));
          // the inputstream is closed by default, so we don't need to close it here
          Blob blob = storage.create(BlobInfo.newBuilder(BUCKET_NAME, fileName).setAcl(acls).build(),
                  filePart.getInputStream());
      
          // return the public download link
          resp.getWriter().print(blob.getMediaLink());
      }
      

      所有这些都发生在后端,因此用户不知道您使用什么服务来上传文件,这正是您想要的。

      在这种特殊情况下,请确保避免使用以下线条:

      resp.getWriter().print(blob.getMediaLink()); 写上传服务的地址:

      https://www.googleapis.com/download/storage/v1/b/my-bucket-name/o/file-name.zip?generation=1524137198335299&amp;alt=media

      还有在前端,一行告诉用户:

      <p>Select a file to upload to your Google Cloud Storage bucket.</p>
      

      【讨论】:

      • 我们可以在一段时间后使公共链接失效吗?
      猜你喜欢
      • 2019-04-10
      • 1970-01-01
      • 1970-01-01
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多