How to securely upload your image files to Cloud Storage using NodeJS.

Theo Okafor
4 min readNov 18, 2019

--

If you have worked on a web application, you might have encountered the problem of image or video file uploads. My preferred way of doing this is to upload the files to a cloud storage platform and save the URL to the Database. Most people prefer to handle such uploads from the browser. The problem with this method is that the cloud API credentials gets bundled inside the JS files and thus made public via the browser. To save the API credentials from cheeky users, we need to take a different approach.

nodeJs and cloudinary

This post/tutorial is about how you can securely handle images and video files using NodeJS and a cloud storage technology like Cloudinary.

To achieve this, we need to store the cloud API details in a NodeJS server (away from the browser). We also need to create the cloud upload mechanism there. This creates a problem, which is that we need to send the image or video to the NodeJS server first before we can be able to upload it to the cloud. To achieve this we need to transport the image as binary data to the server, and then transform it to something that the cloud server expects so that the upload can happen successfully. To secure our server’s API endpoint that we need to use CORS whitelist.

Let me dive right into it.

Create an account with Cloudinary or other Cloud Storage platform of your choice.

This is the first step. You will get an API_KEY and some other account details that will enable you to upload your files to your cloud account.

cloudinary details on dashboard

Create a Node/Express Server to handle your image upload to Cloudinary.

Step 1:

Run npm init to initialise the package.json file for you.

Step 2:

For this app we will be needing express, dotenv, multer, cloudinary, cors, and datauri packages from npm. Let’s install them now. I will explain what they do later.

Run npm install -S express dotenv multer datauri cloudinary cors to install the dependencies.

Step 3:

Create an index.js file and initialise it with some code like below

initial index.js

Run node index.js to ensure that everything works correctly. You should see: Express server is running on 5000 on your console.

Step 4:

Setup your endpoint to use multer for handling your file payload. (You can read more about multer here)

  1. First require multer in the index.js file by doing
  2. const multer = require('multer');
  3. const upload = multer();
  4. Add multer as a middleware to the /cloud-upload route like this

app.post(‘/cloud-upload’, upload.single(‘file’), (request, response) => {}

This is what the index.js file will look like at this point:

Step 5:

Restrict access to the endpoint using CORS.

Part of the reasons we are taking this long approach is that we want to secure our Cloudinary account from unauthourised access. Having a NodeJS server only protects our account details. We need to also protect our upload endpoint as well otherwise anybody that knows the endpoint can upload stuff to our Cloudinary account. To do that we’re going to use the good old CORS.

  1. First, require cors in the index.js file by doing
  2. const cors = require('cors');
  3. Setup CORS whitelist to allow access to only your UI server
  4. Add the setup as a middleware to your /cloud-upload route

Your index.js file should look like this at this point:

index.js with CORS restrictions

Step 6:

Handling the request data in binary using the datauri package.

  1. First require datauri and path in the index.js file.
  2. Instantiate datauri; const dataUri = new DataUri();
  3. Setup the dataUri to transform our image data in buffer format to a readable url format that Cloudinary can understand.

At this point, the index.js file should look like this(pay attention to the API endpoint):

Step 7:

Add the Cloudinary NodeJS setup. View the npm docs or the cloudinary Node SDK docs

  1. Add your cloud credentials to a .env file on the same level as the index.js
  2. Require dotenv
  3. Do dotenv.config(); to setup dotenv

My setup looks like this at this point:

Run node index.js to ensure that everything works correctly.

At this point you can test out the endpoint using POSTMAN (you might need to remove the CORS restriction to be able to test).

Using postman

Setup your web app to use this endpoint for uploads

My setup in the browser is very simplistic. I am using axios from the CDN. It looks like this:

Below is .gif file of the setup working.

That’s it!

A Recap on What We have Covered

  1. Create an account with Cloudinary or other Cloud Storage platform of your choice and obtain the Account credentials required.
  2. Create Node/Express Server to handle your image upload to Cloudinary. Add multer to the file in your payload; adddatauri to convert the buffer object from your payload to a format that Cloudinary can read; add CORS to restrict access to your endpoint to only apps that your want;
  3. Setup your web app to use your upload API endpoint.

Here is the link to the repo containing the assets that I used in this tutorial. Feel free to use it.

Thanks for reading!

--

--

Theo Okafor

Software Engineer. Loves to play Coldplay on repeat while coding JavaScript and Python apps.