Skip to content

Instantly share code, notes, and snippets.

@saturngod
Forked from ToshY/BunnyVOD.php
Last active March 22, 2023 21:08
Show Gist options
  • Save saturngod/01ca507ee0134c38f85874cc4061b320 to your computer and use it in GitHub Desktop.
Save saturngod/01ca507ee0134c38f85874cc4061b320 to your computer and use it in GitHub Desktop.
BunnyCDN VOD HLS Token Authentication V2 with directory tokens
<?php
function sign_bcdn_url($url, $securityKey, $expiration_time = 3600, $user_ip = NULL, $is_directory_token = false, $path_allowed = NULL, $countries_allowed = NULL, $countries_blocked = NULL)
{
if(!is_null($countries_allowed))
{
$url .= (parse_url($url, PHP_URL_QUERY) == "") ? "?" : "&";
$url .= "token_countries={$countries_allowed}";
}
if(!is_null($countries_blocked))
{
$url .= (parse_url($url, PHP_URL_QUERY) == "") ? "?" : "&";
$url .= "token_countries_blocked={$countries_blocked}";
}
$url_scheme = parse_url($url, PHP_URL_SCHEME);
$url_host = parse_url($url, PHP_URL_HOST);
$url_path = parse_url($url, PHP_URL_PATH);
$url_query = parse_url($url, PHP_URL_QUERY);
$parameters = array();
parse_str($url_query, $parameters);
// Check if the path is specified and ovewrite the default
$signature_path = $url_path;
if(!is_null($path_allowed))
{
$signature_path = $path_allowed;
$parameters["token_path"] = $signature_path;
}
// Expiration time
$expires = time() + $expiration_time;
// Construct the parameter data
ksort($parameters); // Sort alphabetically, very important
$parameter_data = "";
$parameter_data_url = "";
if(sizeof($parameters) > 0)
{
foreach ($parameters as $key => $value)
{
if(strlen($parameter_data) > 0)
$parameter_data .= "&";
$parameter_data_url .= "&";
$parameter_data .= "{$key}=" . $value;
$parameter_data_url .= "{$key}=" . urlencode($value); // URL encode everything but slashes for the URL data
}
}
// Generate the toke
$hashableBase = $securityKey.$signature_path.$expires;
// If using IP validation
if(!is_null($user_ip))
{
$hashableBase .= $user_ip;
}
$hashableBase .= $parameter_data;
// Generate the token
$token = hash('sha256', $hashableBase, true);
$token = base64_encode($token);
$token = strtr($token, '+/', '-_');
$token = str_replace('=', '', $token);
if($is_directory_token)
{
return "{$url_scheme}://{$url_host}/bcdn_token={$token}&expires={$expires}{$parameter_data_url}{$url_path}";
}
else
{
return "{$url_scheme}://{$url_host}{$url_path}?token={$token}{$parameter_data_url}&expires={$expires}";
}
}
// Single URL signing example
echo sign_bcdn_url(
"http://sample-stg.b-cdn.net/smaple_video/playlist.m3u8", // Url to sign
"8ba11a7a-f924-8e79-beab-97d111191ad4", // Token Key
360000, // Expiration time in seconds
NULL, // User IP
true,
"/smaple_video/"); // Directory token
@ToshY
Copy link

ToshY commented Oct 7, 2020

Hmm I saw your comment and decided to check this out. Directory tokens should be available for version 2, so why don't I see a &token_ver=2 in the query parameters? I'm just wondering if this will actually work without that 🤔 This new script works with directory tokens indeed. The only issue with IP validation is that users with IPv6 will not work, as BunnyCDN only supports IPv4 for IP validation. So you should use a service like this for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment