BunnyCDN Support Hub

Guides, troubleshooting and support requests to help you get started with BunnyCDN.

How to set up CDN URL Token Authentication

URL Token Authentication allows you to generate secure URLs that expire after the set timestamp and are only accessible using a token generated using a secret key and an expiry timestamp. This guide will explain how to set up the CDN URL Token Authentication on BunnyCDN.

Step 1: Enable URL Token Authentication on your Pull Zone

To generate the secure token, you will first need to enable URL Token Authentication in the Dashboard and then copy your Token security key from the URL Token Authentication box.

Step 2: Generate the URL

To create a secure URL, you must add a token and expires query parameter to the URL that you want to access. Set the expires parameter to the UNIX timestamp to the last timestamp that you want the file to be accessible. After this timestamp, the file will no longer be accessible with this token. For example:


Would mean that the last second your file is accessible would be on Monday, 29 Feb 2016 at 16:02:50 +0000

All you need to do now is to generate the secure token. To do this you can either use one of our code examples or follow algorithm at the bottom of the guide.

PHP example:

$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 .= "";
$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}";

C# .NET example:

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 += "";

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}";

Node.JS JavaScript example:

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 += "";

// 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;

Python example:

#!/usr/bin/env python3
import hashlib
from base64 import b64encode
from time import time

def generate_secure_url(security_key, path,
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')



The token is a Base64 encoded result of a raw 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 ''


  • 0
    Daniel Lo Nigro

    With .NET 4.6 or .NET Core, you can use DateTimeOffset.Now.AddHours(1).ToUnixTimeSeconds() instead of having to define that unixBaseTime variable.

Please sign in to leave a comment.