3
votes

I need to secure client side upload to cloudinary, So that I generated a signature token from my node server side using cloudinary api_secret key and time, used this code api_sign_request = function(params_to_sign, api_secret). After these how to upload the image to cloudinary from front end side using this token

3
Firstly upload it to your server and then from your server upload it to cloudinary server.Prashant Pokhriyal
@PrashantPokhriyal Now I am using this method only, I need to change this to client side for better performanceSameer Ek
If you want to shift to client side then it's not a good design, because then the unauthenticated user can also use that and can upload to your cloudinary server. Cloudnary does give jquery sdk and javascript sdk for integration and you don't need nodejs for that. But again as I said it is not good design. If you really want to go with client side then I sugest you to use upload widgetPrashant Pokhriyal

3 Answers

4
votes

Let's all take a moment to point out how horrible Cloudinary's documentation is. It's easily the worst i've ever seen. Nightmare fuel.

Now that i've got that off my chest... I really needed to be able to do this and I spent way too long banging my head against walls for what should be extremely simple. Here it is...

Server (Node.js)

You'll need an endpoint that returns a signature-timestamp pair to the frontend:

import cloudinary from 'cloudinary'

export async function createImageUpload() {
  const timestamp = new Date().getTime()
  const signature = await cloudinary.utils.api_sign_request(
    {
      timestamp,
    },
    process.env.CLOUDINARY_SECRET
  )
  return { timestamp, signature }
}

Client (Browser)

The client makes a request to the server for a signature-timestamp pair and then uses that to upload a file. The file used in the example should come from an <input type='file'/> change event etc.

const CLOUD_NAME = process.env.CLOUDINARY_CLOUD_NAME
const API_KEY = process.env.CLOUDINARY_API_KEY

async function uploadImage(file) {
  const { signature, timestamp } = await api.post('/image-upload')
  const form = new FormData()
  form.append('file', file)
  const res = await fetch(
    `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/image/upload?api_key=${API_KEY}&timestamp=${timestamp}&signature=${signature}`,
    {
      method: 'POST',
      body: form,
    }
  )
  const data = await res.json()
  return data.secure_url
}

That's it. That's all it takes. If only Cloudinary had this in their docs.

Many thanks to @jpschroeder's answer, which pointed me in the right direction from the start.

1
votes

As far as I know there is currently (Jan, 2020) no documented way to generate secure signed URLs for uploading files like you would with S3. That's not to say it can't be done because the documentation hints that there is a way to do it, but I can't seem to find where to explains it.

This means you can only use Cloudinary’s "unsigned" uploads API, which seems borderline abandoned at this point since the only front end upload SDK they have is only for jQuery. Yeah...jQuery – if you've never heard of it don't be embarrassed, us old timers used to use it back in the old days while we listened to nirvana on cassette tape.

They do have 1 broken example on CodePen of doing an unsigned upload from the browser via vanilla JS. My personal axios/ES2015 example is this:

import axios from 'axios'

const cloudName = 'foofoo'
const unsignedUploadPrefix = 'foobar'
const url = `https://api.cloudinary.com/v1_1/${cloudName}/upload`

document.getElementById('fileinput').addEventListener('change', (e) => {
  const data = new FormData()  
  const file = e.target.files[0]
  data.append('upload_preset', unsignedUploadPrefix)
  data.append('file', file)
  axios.post(url, data)
})
-1
votes

Using our upload widget is a good way to go if you want to have client-side uploading.

What you could also try is to have unsigned uploads using the browser, which we also support.

Although they are less secure than signed uploads, they require to configure an upload preset which can be done only from your end and can be changed immediately to prevent abuse.