How to get Signed URL of CloudFlare Stream video – PHP?

The CloudFlare stream API is a better option to host your video and embed on your websites. However, the documentation is little confusing and blunt in terms of generating signed URL.

What’s Signed URL?

When you embed a CloudFlare stream video on your website, you enter the plain video ID in the <stream> tag. This allows the video to be embedded in any website. Anyone can view the source code of the website, copy the video ID and embed the same in their website. If you want the video to be embedded only on the websites you own, Signed URLs come to help.

CloudFlare gives you a signing key with which you generate JWT signed URL of the video.

 

Step 1 – Generate Key:

$account_id = "Your CloudFlare Account ID";
$bearer_token = "Your CloudFlare Bearer Token";
$cloudflare_email = "Your CloudFlare account Email ID";

$target_url = "https://api.cloudflare.com/client/v4/accounts/{$account_id}/stream/keys";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-Auth-Email: '.$cloudflare_email,
'Authorization: Bearer '.$bearer_token
));
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST,1);
$result=curl_exec ($ch);
curl_close ($ch);
$response = @json_decode($result, true);
if ($response !== null && json_last_error() === JSON_ERROR_NONE)
{
    if(isset($response['success']))
    {
        if($response['success'])
        {
           $key = $response['result'];
           $key_json = "certs/cf_signing_key.json";
           $key_private = "certs/cf_signing_key.key";
           file_put_contents($key_json, json_encode($key)); // save the JSON response
           file_put_contents($key_private, base64_decode($response['result']['pem'])); // save as RSA Private Key
           echo "The signing key is successfully saved.";
        }
        else echo "Generating key failed. CF returned some error.";
    }
    else echo "Generating key failed. CF returned some error.";
}
else echo "The response from CF is not a valid JSON";

Now we have the signing key. We need two elements from the above files,

  1. The key ID stored in the JSON file
  2. The RSA private key.

As per the documentation, CloudFlare provided an endpoint for generating the signed URL, however that does not work, and is throwing the following error,

401 unauthorized failed to verify signature

Therefore I used a third-party library firebase/php-jwt to generate the Signed URL. This can be installed with Composer.

 

Step 2 – Generate Signed URL:

include_once FCPATH."vendor/autoload.php";
use \Firebase\JWT\JWT;
$video_id = "Your Video ID";
$key_json = json_decode(file_get_contents("certs/cf_signing_key.json"), true);
$key_id = $key_json['id'];
$privateKey = file_get_contents("certs/cf_signing_key.key");
$token = ["sub" => $videoID, "kid" => $key_id); // You can also use other parameters as mentioned in CF documentation as required
$signed_url = JWT::encode($token, $privateKey, 'RS256');

 

Step 3 – Stream with Signed URL:

Now embed the stream with the signed URL as,

<stream src="<?php echo $signed_url; ?>" controls></stream>
<script src="https://embed.videodelivery.net/embed/r4xu.fla9.latest.js"></script>
How to get Signed URL of CloudFlare Stream video – PHP?
Scroll to top