Search code examples
node.jsfile-uploaduploadcloudstorage

Upload a file to a cloud storage without exposing an API token


To upload a file from a client to a cloud storage we need an API token.

At the same time, an API token should be keeped privately.

As far as I understand, the easiest implementation would be:

  1. To upload a file locally to the application server

  2. From the application server to upload a file already to a cloud storage using an API.

The biggest issue of this approach is an extra traffic and overloading of the application server, which I really want to avoid.

Is there any way to upload a file directly to a cloud without exposing an API token on a client side? Perhaps, there is some redirect or forward command, which allows to add an API token to the initial request and then to redirect a request with a file to a cloud, or something similar?


Solution

  • If the cloud storage offers an API that allow streaming of the file, for example, in a PUT-request, you can use busboy to upload a file that is sent by an HTML <form>. The following code converts the incoming stream of type multipart/form (which comes from the browser) into an outgoing stream of the file's MIME-type (which goes to the cloud storage API):

    app.post("/uploadform", function(req, res) {
      req.pipe(busboy({headers: req.headers})
        .on("file", function(name, file, info) {
          file.pipe(https.request("<cloud storage endpoint>", {
            headers: {
              "Authorization": "<API token>",
              "Content-Type": info.mimeType
            },
            method: "PUT"
          }).on("response", function(r) {
            res.send("Successfully uploaded");
          }));
      }));
    });
    

    The advantage of this approach is that the file is not stored on the application server. It only passes through the application server's memory chunk by chunk.