Token authentication (basic)

The basic URL Token Authentication allows you to easily protect your requests using specially signed URLs. These URLs will expire after the set timestamp and are only accessible using a token generated using a secret key and an expiry timestamp.

For the advanced implementation with more powerful features, please see Token Authentication

🚧

IPv6 support

IPv6 is automatically disabled when token authentication is in use. This is designed to ensure that users always authenticate correctly, such as when an origin may not support a forwarded IPv6 address. User's will be automatically routed to a CDN IPv4 address with this enabled.

Signing procedure

To create a secure URL, you must add a token and expires query parameters to the URL that you want to access. The expires parameter is the UNIX timestamp marking until when the URL is accessible. After this passes, the URL will no longer be accessible.

The token parameter is a Base64 encoded MD5 hash based on the key, URL and any extra parameters. To generate the token, you can use the following algorithm.

MD5(token_security_key + url_path + expiration)

To properly format the token you have to then replace the following characters in the resulting Base64 string: '\n' with '', '+' with '-', '/' with '_' and '=' with ''

An example secure URL will then look like:

https://test.b-cdn.net/assets/favicon.ico?token=m0EMEkV3pNAKFB33gZuv_Q&expires=1456761770

Code examples

$securityKey = 'token_security_key';
$path = '/pathto/file.jpg';

// Set the time of expiry to one hour from now
$expires = time() + 3600; 

// Generate the token
$hashableBase = $securityKey.$path.$expires;

// If using IP validation
// $hashableBase .= "146.14.19.7";

$token = md5($hashableBase, true);
$token = base64_encode($token);
$token = strtr($token, '+/', '-_');
$token = str_replace('=', '', $token);  

// Generate the URL
$url = "https://myzone.b-cdn.net{$path}?token={$token}&expires={$expires}";
var securityKey = "token_security_key";
var path = "/pathto/file.jpg";

// Load the current time
var unixBaseTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc);
var currentTime = ((long)(DateTime.UtcNow - unixBaseTime).TotalSeconds);

// Set the time of expiry to one hour from now
var expires = currentTime + 3600; 

// Generate the token
System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();

string hashableBase = securityKey + path + expires;

// If using IP validation
// hashableBase += "146.14.19.7";

byte[] outpufBuffer = md5.ComputeHash(Encoding.UTF8.GetBytes(hashableBase)); 
var token = Convert.ToBase64String(outpufBuffer); 
token = token.Replace("\n", "").Replace("+", "-").Replace("/", "_").Replace("=", ""); 

// Generate the URL 
var url = $"https://myzone.b-cdn.net{path}?token={token}&expires={expires}";
var crypto = require('crypto'),
securityKey = 'token_security_key',
path = '/pathto/file.jpg';

// Set the time of expiry to one hour from now
var expires = Math.round(Date.now() / 1000) + 3600;

var hashableBase = securityKey + path + expires;

// If using IP validation
// hashableBase += "146.14.19.7";

// Generate and encode the token 
var md5String = crypto.createHash("md5").update(hashableBase).digest("binary");
var token = new Buffer(md5String, 'binary').toString('base64');
token = token.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');

// Generate the URL
var url = 'https://myzone.b-cdn.net' + path + '?token=' + token + '&expires=' + expires;
#!/usr/bin/env python3
import hashlib
from base64 import b64encode
from time import time

def generate_secure_url(security_key, path,
                        expire_timeframe=3600,
                        base_url=str(),
                        filtered_ip=""):
    """Generate BunnyCDN URL authentication token.
 
   Arguments:
       security_key (str): Generated token from the panel.
       path (str): /path/to/file.ext, with the initial slash included.
       expire_timeframe (int): Time until expiry, in seconds.
       base_url (str): CDN's base URL of the site, without ending slash.
       filtered_ip: The IP that should be included in the hash. Use this if doing IP validation.

   Returns:
       str: URL
   """
    expire_timestamp = int(time()) + 3600
    token_content = '{key}{path}{timestamp}{filtered_ip}'.format(key=security_key,path=path,timestamp=expire_timestamp)
    md5sum = hashlib.md5()
    md5sum.update(token_content.encode('ascii'))
    token_digest = md5sum.digest()
    token_base64 = b64encode(token_digest).decode('ascii')
    token_formatted = token_base64.replace('\n', '').replace('+', '-').replace('/', '_').replace('=', '')
 
    # Build the URL
    url = '{base_url}{path}?token={token}&expires={expire_timestamp}'.format(
        base_url=base_url,
        path=path,
        token=token_formatted,
        expire_timestamp=expire_timestamp)
 
    return url
 
# Example usage:
# Returns: '/index.html?token=IuNSzXOiYkL-LmGJcwxMQg&expires=1488672404'
generate_secure_url('super-secret-code', '/index.html')

# Returns: 'https://test.b-cdn.net/index.html?token=EuS4D8fFlTrT6zO4FymvUw&expires=1488672453'
generate_secure_url('super-secret-code', '/index.html', 31536000, 'https://test.b-cdn.net')