Deprecated Token Authentication V1
This guide has been deprecated with the introduction of Token Authentication V2. You can still use it to generate tokens with the old system, but we strongly recommend looking at the new How to sign URLs for bunny.net Token Authentication guide.
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 bunny.net.
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 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:
To make things easier, we also provide code examples for most popular languages below.
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 .= "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}";
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 += "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}";
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 += "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;
Python Example
#!/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')