Secure delivery (Signed URLs)
Control who and for how long can access files in your project via Signed URLs. When enabled, a user will require a token to access your content by the link like this:
https://cdn.yourdomain.com/{uuid}/?token=exp={timestamp}~hmac={token}
In other words, Secure delivery is a CDN URL with GET parameters that include the token and its expiration time to access protected content.
Use cases
When to use Secure delivery:
- Users upload personal, medical, and other sensitive data.
- Only an authorized client can access certain content.
- Content access is limited in time.
How Secure delivery works
Contact us to enable the Secure delivery feature.
Prior to using Secure delivery, set up a custom CNAME.
The URL format depends on your custom domain's CDN provider.
Akamai
If using Akamai as a CDN provider, then an example is:
https://cdn.yourdomain.com/{uuid}/?token=exp={timestamp}~acl={acl}~hmac={token}
{uuid}
is a UUID of any file in your Uploadcare project or a URI (UUID + transformations + filename), which is a URL part.{acl}
is an optional Access Control List parameter. It supports wildcards (*
,?
). Also, it can be a string (single path) or an array (multi-paths).
ACL examples to access files with a token:
acl=/*/
– any file in a project.acl=/{uuid}/
– original file with UUID.acl=/{uuid}/-/resize/640x/
– modified file version.
CloudFront
If using CloudFront as a CDN provider, then you need to add two CNAMEs:
- ACM verification (get the value from our support).
cdn.example.com. CNAME example.cfcdn.uploadcare.com
.
If CloudFront is set up with Signed URLs, you need to get the private key and key ID.
More information about Signed URLs creating - AWS Docs and Boto3 Docs.
Limitations
Akamai has a 1GB file size limit. If you need to transfer files larger than 1GB, use Cloudfront.
Token generation
Akamai
Your backend app should take care of generating access tokens. We recommend that you start with ready-made Akamai solutions for popular languages:
Full Akamai implementation guide: Auth Token 2.0 Verification and DD.
CloudFront
The information about using wildcards in the URLs: Creating a signed URL using a custom policy.
Proxy backend example
The proxy backend is an API endpoint of your application. The app needs to resolve the following tasks:
- Accept escaped preview URL as a GET parameter.
- Check user authorization.
- Generate expiring access tokens for that URL.
- Append access tokens to the URL.
- Redirect to that URL.
Don’t forget to check user credentials on your backend. Make sure not to authenticate anonymous user requests. Otherwise using Secure delivey don't make any sense.
Here is a basic proxy backend Node.js app:
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)
})
javascript
Show image previews in File uploader
After uploading, File uploader loads image previews from the CDN:
-> (GET) https://ucarecdn.com/{uuid}/
With Secure delivery on, File Upload can't show previews because Signed URLs include a token part. To work that around, you can load images through a proxy backend, where it can hook up the token info:
-> (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}
Here are two options that can help you show image previews over Secure delivery:
previewProxy
. It proxies the data related to image previews.previewUrlCallback
. It works if you need to send extra data like JWT tokens.
Option previewProxy
Implementing the previewProxy
option works best for these cases:
- Your application uses cookie-based authorization.
- Your proxy backend and your app are located in the same domain (otherwise, cookies won't be sent).
- You don’t need any other image-related data beside URLs.
To use previewProxy
option, specify your proxy backend endpoint URL, and
you're good to go:
UPLOADCARE_PREVIEW_PROXY = 'https://domain.com/preview?'
javascript
It'll let File uploader load image previews via the following URL:
https://domain.com/preview?url=https%3A%2F%2Fcdn.domain.com%2F{uuid}%2F
It appends a query parameter with image preview URL to previewProxy
:
newPreviewUrl = previewProxy + 'url={previewUrl}'
javascript
By default, the uploader uses url
as the query parameter name, but you
can have a custom naming as well:
'https://domain.com/preview?' + 'url={previewUrl}'
'https://domain.com/preview?foo=bar' + '&url={previewUrl}'
'https://domain.com/preview?foo=bar&myUrl=' + '{previewUrl}'
javascript
Option previewUrlCallback
This option provides you with explicit control over the File uploader preview
URLs. In code, previewUrlCallback
is a function with a signature:
(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}`
}
javascript
Note, previewUrlCallback
overrides previewProxy
, and the latter option will
be ignored.