uploadcaredocs

Widget and Secure URLs

Uploadcare allows you to implement a security-focused workflow via Authenticated URLs. That is, you will be able to control who and when have access to your content. To use the feature, you should first set the Custom CNAME.

When using Authenticated URLs, it is still okay to upload files to your project via the File Uploader UI. Showing image previews in the widget dialog becomes a bit more complicated, though. This section introduces the Authenticated URLs workflow and tells you about adequately handling image previews.

Authenticated URLs, Briefly

Authenticated URLs can be useful when:

  • Handling personal, medical or other sensitive data.
  • Rendering content only for authorized users.
  • Only letting users access your content within a specified time frame.

The default Uploadcare workflow implies your uploads go to an Uploadcare project identified by a Public API key. When a file gets uploaded, you receive a CDN URL to address this file. Something like this,

https://ucarecdn.com/85b5644f-e692-4855-9db0-8c5a83096e25/image.jpg

Such URLs are public meaning anyone can access the content by navigating to that link. With Uploadcare, you can control who and when have access to files uploaded to your account. The feature providing such behavior is called Authenticated URLs or Signed URLs. It only works combined with custom domains, and when enabled, users will require a token and a timestamp to access your content. Your URLs will then change to the following form (which may vary depending on the CDN provider):

https://cdn.yourdomain.com/{uuid}/?token=exp={timestamp}~acl=/{uuid}/~hmac={token}

Signed URLs and Image Previews

Uploadcare Widget is an Upload API client. This means that every file uploaded using the widget dialog first goes to our upload instances, then storage, and finally CDN. The widget then gets that CDN URL and loads its content to render a preview. This works just fine when every CDN URL related to your Uploadcare account is public.

Once you enable the Authenticated URLs feature, the widget will not be able to show image previews because it’s unaware of your tokens. To handle this correctly, you will need a widget to proxy requests through your proxy backend.

Without using Authenticated URLs, the widget loads images directly from our CDN:

-> (GET) https://ucarecdn.com/{uuid}/

Enabling Authenticated URLs requires the widget to load images through your proxy backend:

-> (GET) https://domain.com/preview?url=https%3A%2F%2Fcdn.domain.com%2F{uuid}%2F
-> (Redirect) https://cdn.domain.com/{uuid}/?token={token}&expire={expire}

The behavior described above is provided by the two widget options: previewProxy and previewUrlCallback. Depending on your use case, you can implement one or another.

Option previewProxy

Implementing the previewProxy option suits the following use cases:

  • Your application uses cookie-based authorization.
  • Your proxy backend and your app are located in the same domain (otherwise cookies will not be sent).
  • You don’t need any other image-related data beside URLs.

In the case you do want to send extra data to your proxy backend, consider using the previewUrlCallback option instead. JWT tokens or image metadata are good examples of those extras.

To go with the previewProxy option, you are only required to specify a URL for your proxy backend endpoint. For instance:

UPLOADCARE_PREVIEW_PROXY = 'https://domain.com/preview?'

Your widget will now load image previews via the following URL:

https://domain.com/preview?url=https%3A%2F%2Fcdn.domain.com%2F{uuid}%2F

As you can see, it simply appends a query parameter holding the image preview URL to your previewProxy option, i.e.:

newPreviewUrl = previewProxy + 'url={previewUrl}'

By default, the uploader uses url as the query parameter name. However, you can also implement some different naming, e.g.:

'https://domain.com/preview?' + 'url={previewUrl}'
'https://domain.com/preview?foo=bar' + '&url={previewUrl}'
'https://domain.com/preview?foo=bar&myUrl=' + '{previewUrl}'

Option previewUrlCallback

In case you want full control over the widget preview URLs, go with the previewUrlCallback option. The option gets assigned a function with a signature like:

(previewUrl, fileInfo) => previewUrl

Example:

UPLOADCARE_PREVIEW_URL_CALLBACK = function(previewUrl, fileInfo) {
    const jwtToken = getJWTToken()
    return `https://domain.com/preview?` +
      `url=${encodeURIComponent(previewUrl)}&` +
      `uuid=${fileInfo.uuid}&` +
      `token=${jwtToken}`
}

When you specify the previewUrlCallback option, previewBase will be ignored. So, it’s either one option or another, not both.

Proxy Backend

The proxy backend is an API endpoint of your application.

It should be capable of doing the following:

  • Accept escaped preview URL as GET parameter.
  • Check user authorization.
  • Generate expired access tokens for that URL.
  • Append access tokens to the URL.
  • Send redirect to that URL.

The list above covers the basics; you can further extend it if you want.

Don’t forget to check user credentials on your backend. Make sure not to authenticate anonymous user requests, unless you want to.

Proxy Backend Example

Here is how your basic proxy backend could look like for Node.js,

app.get('/preview', (req, res) => {
  const url = req.query.url
  const user = req.user

  if (!user) {
    res.status(403).send('Authorization failed')
    return
  }

  const expire = Math.round(Date.now() / 1000) + 120
  const token = generateToken(url, expire)

  const secureUrl = url + `?token=${token}&expire=${expire}`

  res.redirect(secureUrl)
})

We’re always happy to help with code, integration, and other stuff. Search our site for more info or post your question in our Community Area.