Signed uploads
On this page
With signed uploads, you get to control who can and when can upload files to one of your Uploadcare projects. You need to generate a token on your backend, and a trusted user should use this token to upload a new file. It works with both Uploadcare File Uploader and Upload API.
Turning signed uploads on
Signed uploads can be turned on and off to an Uploadcare project, because it has a dedicated storage, Public and Private keys, and security settings.
- Go to your Dashboard and select an existing project or create a new one. Open the project.
- Click Enable next to Signed Uploads.
From now on, every request to Upload API should include a signature
part
(token). However, you'll still be able to upload files to your project on the
website via the Dashboard.
Token generation
The token is called signature
. Technically, it's a string sent along with your
upload request. It requires your Uploadcare project's Secret Key.
The signature
is an HMAC/SHA256 with two parameters:
YOUR_SECRET_KEY
— a generated keyexpire
— an expiration time message (string)
Here's how to make a signature
on your backend in Python:
import time
import hashlib
import hmac
def generate_secure_signature(secret, expire):
k, m = secret, str(expire).encode('utf-8')
if not isinstance(k, (bytes, bytearray)):
k = k.encode('utf-8')
return hmac.new(k, m, hashlib.sha256).hexdigest()
# Expire in 30 min, e.g., 1454903856
expire = int(time.time()) + 60 * 30
# Secret key of your project
secret = 'YOUR_SECRET_KEY'
# Example result: '9890adc8886d27c93befed595abfbca514b7592a88e2f64dbddbea2d369a68dc'
signature = generate_secure_signature(secret, expire)
python
Making signature
in Node.js:
const crypto = require('crypto');
function generateSignature(secret, expire) {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(expire);
return hmac.digest('hex');
}
// secret key
const secret = 'YOUR_SECRET_KEY';
// define expiry (e.g. 120 seconds)
const expire = (Math.round(Date.now() / 1000) + 120).toString();
const signature = generateSignature(secret, expire);
javascript
Making signature
in Ruby:
require "openssl" # if necessary
def generate_signature(secret, expire_at)
OpenSSL::HMAC.hexdigest("SHA256", secret, expire_at.to_i.to_s)
end
secret = 'secret'
expire_at = Time.now + 60 * 2 # 2 minutes from now
generate_signature(secret, expire_at)
ruby
Making signature
in JS API clients:
import { generateSecureSignature } from '@uploadcare/signed-uploads'
// by the expiration timestamp in milliseconds since the epoch
const { secureSignature, secureExpire } = generateSecureSignature('YOUR_SECRET_KEY', {
expire: Date.now() + 60 * 30 * 1000 // expire in 30 minutes
})
// by the expiration date
const { secureSignature, secureExpire } = generateSecureSignature('YOUR_SECRET_KEY', {
expire: new Date("2099-01-01") // expire on 2099-01-01
})
// by the lifetime in milliseconds
const { secureSignature, secureExpire } = generateSecureSignature('YOUR_SECRET_KEY', {
lifetime: 60 * 30 * 1000 // expire in 30 minutes
})
javascript
expire
explained
The expire
string sets the expiration date and time or duration for a
signature
. It has a Unix time format.
The expire
function in the Python example above adds a certain duration after
the generation time. In this case, 30 minutes:
# Expire in 30 min, e.g., 1454903856
expire = int(time.time()) + 60 * 30
python
Signed uploads example
Request:
curl -F "UPLOADCARE_PUB_KEY=caa9d29da887ee88ffe6" \
-F "signature=46f70d2b4fb6196daeb2c16bf44a7f1e" \
-F "expire=1454903856" \
-F "file=@image.jpg" \
"https://upload.uploadcare.com/base/"
bash
Response:
{
"file": "c0d776d4-8c8e-47df-9e92-03b68b99c2ba"
}
json
To work with File Uploader, install and configure it first. Then specify the secure signature and secure expire options.
Possible errors
Both signature
and an active expire
are required for every upload request
and should be valid. The list of possible errors:
[HTTP 400] 'signature' is required.
json
[HTTP 400] 'expire' is required.
json
If expire
is not a valid Unix timestamp:
[HTTP 400] 'expire' must be a UNIX timestamp.
json
If your signature
has expired, i.e., expire < now
:
[HTTP 403] Expired signature.
json
If signature
is incorrect:
[HTTP 403] Invalid signature.
json