Menu
AWS SDK for PHP
Developer Guide

Signing Amazon CloudFront URLs with AWS SDK for PHP version 3

Signing CloudFront URLs for Private Distributions

Signed URLs enable you to provide users access to your private content. A signed URL includes additional information (e.g., expiration time) that gives you more control over access to your content. This additional information appears in a policy statement, which is based on either a canned policy or a custom policy. For information about how to set up private distributions and why you need to sign URLs, see Serving Private Content through Amazon CloudFront in the Amazon CloudFront Developer Guide.

You can sign a URL using the CloudFront client in the SDK. First, you must create a CloudFrontClient object.

<?php $cloudFront = new Aws\CloudFront\CloudFrontClient([ 'region' => 'us-west-2', 'version' => '2014-11-06' ]);

You can sign a CloudFront URL for a video resource using either a canned or custom policy.

// Set up parameter values for the resource $resourceKey = 'rtmp://example-distribution.cloudfront.net/videos/example.mp4'; $expires = time() + 300; // Create a signed URL for the resource using the canned policy $signedUrlCannedPolicy = $cloudFront->getSignedUrl([ 'url' => $resourceKey, 'expires' => $expires, 'private_key' => '/path/to/your/cloudfront-private-key.pem', 'key_pair_id' => '<CloudFront key pair id>' ]);

To use a custom policy, provide the policy key instead of expires.

$customPolicy = <<<POLICY { "Statement": [ { "Resource": "{$resourceKey}", "Condition": { "IpAddress": {"AWS:SourceIp": "{$_SERVER['REMOTE_ADDR']}/32"}, "DateLessThan": {"AWS:EpochTime": {$expires}} } } ] } POLICY; // Create a signed URL for the resource using a custom policy $signedUrlCustomPolicy = $cloudFront->getSignedUrl([ 'url' => $resourceKey, 'policy' => $customPolicy, 'private_key' => '/path/to/your/cloudfront-private-key.pem', 'key_pair_id' => '<CloudFront key pair id>' ]);

The form of the signed URL is actually different depending on whether the URL you are signing is using the "http" or "rtmp" scheme. In the case of "http", the full, absolute URL is returned. For "rtmp", only the relative URL is returned for your convenience. This is because some players require the host and path to be provided as separate parameters.

The following example shows how you could use the signed URL to construct a webpage that displays a video using JWPlayer. The same type of technique would apply to other players such as FlowPlayer, but require different client-side code.

<html> <head> <title>|CFlong| Streaming Example</title> <script type="text/javascript" src="https://example.com/jwplayer.js"></script> </head> <body> <div id="video">The canned policy video will be here.</div> <script type="text/javascript"> jwplayer('video').setup({ file: "<?= $streamHostUrl ?>/cfx/st/<?= $signedUrlCannedPolicy ?>", width: "720", height: "480" }); </script> </body> </html>

Signing CloudFront Cookies for Private Distributions

As an alternative to signed URLs, you can also grant clients access to a private distribution via signed cookies. Signed cookies enable you to provide access to multiple restricted files, such as all of the files for a video in HLS format or all of the files in the subscribers' area of a website. For more information on why you might want to use signed cookies instead of signed URLs (or vice versa), see Choosing Between Signed URLs and Signed Cookies in the Amazon CloudFront Developer Guide.

Creating a signed cookie is similar to creating a signed URL. The only difference is the method called (getSignedCookie instead of getSignedUrl).

<?php $cloudFront = new Aws\CloudFront\CloudFrontClient([ 'region' => 'us-west-2', 'version' => '2014-11-06' ]); // Set up parameter values for the resource $resourceKey = 'https://example-distribution.cloudfront.net/videos/example.mp4'; $expires = time() + 300; // Create a signed cookie for the resource using the canned policy $signedCookieCannedPolicy = $cloudFront->getSignedCookie([ 'url' => $resourceKey, 'expires' => $expires, 'private_key' => '/path/to/your/cloudfront-private-key.pem', 'key_pair_id' => '<CloudFront key pair id>' ]);

As with getSignedUrl, you can provide a 'policy' parameter instead of an expires parameter and a url parameter to sign a cookie with a custom policy. A custom policy can contain wildcards in the resource key. This enables you to create a single signed cookie for multiple files.

$customPolicy = <<<POLICY { "Statement": [ { "Resource": "{$resourceKey}", "Condition": { "IpAddress": {"AWS:SourceIp": "{$_SERVER['REMOTE_ADDR']}/32"}, "DateLessThan": {"AWS:EpochTime": {$expires}} } } ] } POLICY; // Create a signed cookie for the resource using a custom policy $signedCookieCustomPolicy = $cloudFront->getSignedCookie([ 'policy' => $customPolicy, 'private_key' => '/path/to/your/cloudfront-private-key.pem', 'key_pair_id' => '<CloudFront key pair id>' ]);

getSignedCookie returns an array of key-value pairs, all of which must be set as cookies to grant access to a private distribution.

foreach ($signedCookieCustomPolicy as $name => $value) { setcookie($name, $value, 0, "", "example-distribution.cloudfront.net", true, true); }

You can also pass these cookies to a GuzzleHttp\Cookie\CookieJar for use with a Guzzle client.

use GuzzleHttp\Client; use GuzzleHttp\Cookie\CookieJar; $distribution = "example-distribution.cloudfront.net"; $client = new \GuzzleHttp\Client([ 'base_uri' => "https://$distribution", 'cookies' => CookieJar::fromArray($signedCookieCustomPolicy, $distribution), ]); $client->get('video.mp4');

For more information, see Using Signed Cookies in the Amazon CloudFront Developer Guide.