Signing Amazon CloudFront URLs with AWS SDK for PHP Version 3
Signed URLs enable you to provide users access to your private content. A signed URL includes additional information (for example, 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.
-
Create a signed Amazon CloudFront URL using getSignedURL.
-
Create a signed Amazon CloudFront cookie using getSignedCookie.
All the example code for the AWS SDK for PHP Version 3 is available here on GitHub.
Credentials
Before running the example code, configure your AWS credentials, as described in Credentials for the AWS SDK for PHP Version 3. Then import the AWS SDK for PHP, as described in Basic Usage Patterns of the AWS SDK for PHP Version 3.
For more information about using Amazon CloudFront, see the Amazon CloudFront Developer Guide.
Signing CloudFront URLs for Private Distributions
You can sign a URL using the CloudFront client in the SDK. First, you must
create a CloudFrontClient
object.
You can sign a CloudFront URL for a video resource using either a canned or
custom policy.
Imports
require 'vendor/autoload.php'; use Aws\CloudFront\CloudFrontClient; use Aws\Exception\AwsException;
Sample Code
// Create a CloudFront Client $client = new Aws\CloudFront\CloudFrontClient([ 'profile' => 'default', 'version' => '2014-11-06', 'region' => 'us-east-2' ]); // 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 = $client->getSignedUrl([ 'url' => $resourceKey, 'expires' => $expires, 'private_key' => '/path/to/your/cloudfront-private-key.pem', 'key_pair_id' => '<CloudFront key pair id>' ]);
Use a Custom Policy When Creating CloudFront URLs
To use a custom policy, provide the policy
key instead of expires
.
Imports
require 'vendor/autoload.php'; use Aws\CloudFront\CloudFrontClient; use Aws\Exception\AwsException;
Sample Code
// Create a CloudFront Client $client = new Aws\CloudFront\CloudFrontClient([ 'profile' => 'default', 'version' => '2014-11-06', 'region' => 'us-east-2' ]); // Set up parameter values for the resource $customPolicy = <<<POLICY { "Statement": [ { "Resource": "{$resourceKey}", "Condition": { "IpAddress": {"AWS:SourceIp": "{$_SERVER['REMOTE_ADDR']}/32"}, "DateLessThan": {"AWS:EpochTime": {$expires}} } } ] } POLICY; $resourceKey = 'rtmp://example-distribution.cloudfront.net/videos/example.mp4'; // Create a signed URL for the resource using the canned policy $signedUrlCannedPolicy = $client->getSignedUrl([ 'url' => $resourceKey, 'policy' => $customPolicy, 'private_key' => '/path/to/your/cloudfront-private-key.pem', 'key_pair_id' => '<CloudFront key pair id>' ]); foreach ($signedUrlCannedPolicy as $name => $value) { setcookie($name, $value, 0, "", "example-distribution.cloudfront.net", true, true); }
Use a CloudFront Signed URL
The form of the signed URL differs, 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 that is called (getSignedCookie
instead of getSignedUrl
).
Imports
require 'vendor/autoload.php'; use Aws\CloudFront\CloudFrontClient; use Aws\Exception\AwsException;
Sample Code
// Create a CloudFront Client $client = new Aws\CloudFront\CloudFrontClient([ 'profile' => 'default', 'version' => '2014-11-06', 'region' => 'us-east-2' ]); // 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 = $client->getSignedCookie([ 'url' => $resourceKey, 'expires' => $expires, 'private_key' => '/path/to/your/cloudfront-private-key.pem', 'key_pair_id' => '<CloudFront key pair id>' ]);
Use a Custom Policy When Creating CloudFront Cookies
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.
getSignedCookie
returns an array of key-value pairs, all of which must
be set as cookies to grant access to a private distribution.
Imports
require 'vendor/autoload.php'; use Aws\CloudFront\CloudFrontClient; use Aws\Exception\AwsException;
Sample Code
// Create a CloudFront Client $client = new Aws\CloudFront\CloudFrontClient([ 'profile' => 'default', 'version' => '2014-11-06', 'region' => 'us-east-2' ]); // Set up parameter values for the resource $resourceKey = 'https://example-distribution.cloudfront.net/videos/example.mp4'; $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 = $client->getSignedCookie([ 'policy' => $customPolicy, 'private_key' => '/path/to/your/cloudfront-private-key.pem', 'key_pair_id' => '<CloudFront key pair id>' ]); foreach ($signedCookieCustomPolicy as $name => $value) { setcookie($name, $value, 0, "", "example-distribution.cloudfront.net", true, true); }
Send CloudFront Cookies to Guzzle Client
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.