Delivering ODI securely using signed URLs
If the Image settings in the account are setup to keep Standard Image Conversion and Custom Conversions as private (non-public), you can still deliver ODI by using secure methods.
This can be done in three ways:-
- by passing
X-FileSpin-Api-Key:{API_KEY}
if the request is made from a server-side application (see Authentication)
Never use the API_KEY when the ODI requests are made from a browser. You will expose the API Key if you do.
- by passing
Authorization: Bearer {JWT}
header in the request if the request is made from a client-side application (see JWT Authentication) - by signing the request URL. See below.
Signed URL for ODI
If Secure On-demand Images option is enabled in your settings, then you must use signed URLs.
To generate a signed URL programmatically, you'll need the below parameters besides the ASSET_ID and ODI parameters:-
Parameter | Type | Description |
---|---|---|
API Key | string | Your API Key. This is available in your Authorization Settings page. |
EXPIRY | integer | Seconds since Unix Epoch time. |
ACCESS_ID | string | Access Id that must be used to sign URLs. You can obtain your account's Access Id from the Authorization Settings page. |
Steps to generate signed URL
Signing a image URL is done by setting an expiry and signing the URL using your FileSpin API_KEY and Access Id. The signing process is as below:-
- Take the URL part staring with the ASSET_ID, excluding the signature part, like
0c3c6d026858460abc4de1dcb4de15ac?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT
, where expiry is seconds since Epoch time - Using your API Key, Access Id and the above URL part as the string-to-sign, calculate the HMAC signature
- Encode the signature to a base64 string, then URL encode the resulting string and append it to the URL as signature query parameter value
Example signed image URL
<<CDN_HOST>>/api/v1/assets/0c3c6d026858460abc4de1dcb4de15ac/conversions?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT&signature=vsR0_NFfeLEJPc8MXWMh2xI2Qvg%3D
Note that the parameter values must be url-encoded otherwise FileSpin may return a authorization error.
Code examples
import base64, hmac, hashlib, urllib
from six import text_type, b
API_KEY = '0c3c6d026858460abc4de1dcb4de15ac'
string_to_sign = '0c3c6d026858460abc4de1dcb4de15ac?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT'
signature = urllib.quote_plus(base64.urlsafe_b64encode(hmac.new(b(API_KEY), text_type(string_to_sign).encode('utf-8'), hashlib.sha1).digest()))
signed_url = '%s%s&signature=%s' % ('<<CDN_HOST>>/api/v1/conversions/',string_to_sign,signature)
Signed URL with java
import java.security.SignatureException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
String api_key = "0c3c6d026858460abc4de1dcb4de15ac";
String string_to_sign = "0c3c6d026858460abc4de1dcb4de15ac?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT";
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(api_key);
byte[] hmac = mac.doFinal(string_to_sign.getBytes());
String signature = Encoding.EncodeBase64(hmac);
String signed_url = "<<CDN_HOST>>/api/v1/conversions/" + string_to_sign + "&signature=" + signature;
Signed URL with nodejs
const crypto = require("crypto");
const API_KEY = "0c3c6d026858460abc4de1dcb4de15ac";
const string_to_sign =
"f99255d2bf8142b29561641491e9940c/conversions?resize=500,500&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT";
const hash = crypto
.createHmac("sha1", API_KEY)
.update(string_to_sign)
.digest("base64");
const signature = encodeURIComponent(hash.replaceAll("/", "_"));
const signed_url = `<<CDN_HOST>>/api/v1/assets/${string_to_sign}&signature=${signature}`;
console.log(signed_url);
Signed URL with php
<?php
$api_key = '0c3c6d026858460abc4de1dcb4de15ac'
$string_to_sign = '0c3c6d026858460abc4de1dcb4de15ac?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT'
$signature = urlencode(base64_encode(hash_hmac('sha1', $string_to_sign, $api_key, true)));
$signed_url = '<<CDN_HOST>>/api/v1/conversions/'.$string_to_sign.'&signature='.$signature
?>