使用AWS SDK for PHP版本 3 对亚马逊 CloudFront 网址进行签名 - AWS SDK for PHP

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用AWS SDK for PHP版本 3 对亚马逊 CloudFront 网址进行签名

您可通过签名 URL 为用户提供对私有内容的访问权限。签名 URL 中包含的其他信息(例如,到期时间)可让您更好地控制对内容的访问。该额外信息出现在策略声明中,且是基于固定策略或自定义策略。有关如何设置私有分配以及为何需要签署网址的信息,请参阅《亚马逊 CloudFront 开发者指南》 CloudFront中的通过亚马逊提供私有内容

  • 使用 getSigne Durl 创建已签名的亚马逊 CloudFront URL。

  • 使用创建已签名的亚马逊 CloudFront Cookie getSignedCookie

的所有示例代码都可以在此AWS SDK for PHP处找到 GitHub

凭证

运行示例代码之前,请配置您的 AWS 凭证,如 凭证 中所述。然后导入 AWS SDK for PHP,如 基本用法 中所述。

有关使用亚马逊的更多信息 CloudFront,请参阅亚马逊 CloudFront 开发者指南

私有发行版的签名 CloudFront URL

您可以使用 SDK 中的 CloudFront 客户端对 URL 进行签名。首先,您必须创建一个 CloudFrontClient 对象。您可以使用固定政策或自定义政策为视频资源签名 CloudFront URL。

导入

require 'vendor/autoload.php'; use Aws\CloudFront\CloudFrontClient; use Aws\Exception\AwsException;

示例代码

function signPrivateDistribution( $cloudFrontClient, $resourceKey, $expires, $privateKey, $keyPairId ) { try { $result = $cloudFrontClient->getSignedUrl([ 'url' => $resourceKey, 'expires' => $expires, 'private_key' => $privateKey, 'key_pair_id' => $keyPairId ]); return $result; } catch (AwsException $e) { return 'Error: ' . $e->getAwsErrorMessage(); } } function signAPrivateDistribution() { $resourceKey = 'https://d13l49jEXAMPLE.cloudfront.net/my-file.txt'; $expires = time() + 300; // 5 minutes (5 * 60 seconds) from now. $privateKey = dirname(__DIR__) . '/cloudfront/my-private-key.pem'; $keyPairId = 'AAPKAJIKZATYYYEXAMPLE'; $cloudFrontClient = new CloudFrontClient([ 'profile' => 'default', 'version' => '2018-06-18', 'region' => 'us-east-1' ]); echo signPrivateDistribution( $cloudFrontClient, $resourceKey, $expires, $privateKey, $keyPairId ); } // Uncomment the following line to run this code in an AWS account. // signAPrivateDistribution();

创建 CloudFront URL 时使用自定义策略

要使用自定义策略,请提供 policy 键,而不是 expires

导入

require 'vendor/autoload.php'; use Aws\CloudFront\CloudFrontClient; use Aws\Exception\AwsException;

示例代码

function signPrivateDistributionPolicy( $cloudFrontClient, $resourceKey, $customPolicy, $privateKey, $keyPairId ) { try { $result = $cloudFrontClient->getSignedUrl([ 'url' => $resourceKey, 'policy' => $customPolicy, 'private_key' => $privateKey, 'key_pair_id' => $keyPairId ]); return $result; } catch (AwsException $e) { return 'Error: ' . $e->getAwsErrorMessage(); } } function signAPrivateDistributionPolicy() { $resourceKey = 'https://d13l49jEXAMPLE.cloudfront.net/my-file.txt'; $expires = time() + 300; // 5 minutes (5 * 60 seconds) from now. $customPolicy = <<<POLICY { "Statement": [ { "Resource": "$resourceKey", "Condition": { "IpAddress": {"AWS:SourceIp": "{$_SERVER['REMOTE_ADDR']}/32"}, "DateLessThan": {"AWS:EpochTime": $expires} } } ] } POLICY; $privateKey = dirname(__DIR__) . '/cloudfront/my-private-key.pem'; $keyPairId = 'AAPKAJIKZATYYYEXAMPLE'; $cloudFrontClient = new CloudFrontClient([ 'profile' => 'default', 'version' => '2018-06-18', 'region' => 'us-east-1' ]); echo signPrivateDistributionPolicy( $cloudFrontClient, $resourceKey, $customPolicy, $privateKey, $keyPairId ); } // Uncomment the following line to run this code in an AWS account. // signAPrivateDistributionPolicy();

使用 CloudFront 签名网址

根据您要签名的 URL 使用的是“HTTP”还是“RTMP”方案,签名后的 URL 的形式将有所不同。如果是“HTTP”方案,将返回完整的绝对 URL。如果是“RTMP”方案,则为了方便起见,只会返回相对 URL。这是因为某些播放器要求分别提供主机和路径参数。

以下示例展示如何使用签名 URL 构造网页,以使用 JWPlayer 显示视频。相同类型的技术也适用于其他玩家 FlowPlayer,例如,但需要不同的客户端代码。

<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>

为私人分发签名 CloudFront Cookie

作为签名 URL 的替代方案,您还可以通过签名 Cookie 为客户端授予对私有分发的访问权限。借助经过签名的 Cookie,您可以提供对多个受限文件的访问权限,例如 HLS 格式视频的所有文件,或在网站订阅者区域中的所有文件。要详细了解为何要使用签名 Cookie 而不是签名网址(反之亦然),请参阅《亚马逊 CloudFront 开发者指南》中的在签名网址和签名 Cookie 之间进行选择

创建签名 cookie 的方法与创建签名 URL 的方法类似。唯一的区别是调用的方法(getSignedCookie,而不是 getSignedUrl)。

导入

require 'vendor/autoload.php'; use Aws\CloudFront\CloudFrontClient; use Aws\Exception\AwsException;

示例代码

function signCookie( $cloudFrontClient, $resourceKey, $expires, $privateKey, $keyPairId ) { try { $result = $cloudFrontClient->getSignedCookie([ 'url' => $resourceKey, 'expires' => $expires, 'private_key' => $privateKey, 'key_pair_id' => $keyPairId ]); return $result; } catch (AwsException $e) { return [ 'Error' => $e->getAwsErrorMessage() ]; } } function signACookie() { $resourceKey = 'https://d13l49jEXAMPLE.cloudfront.net/my-file.txt'; $expires = time() + 300; // 5 minutes (5 * 60 seconds) from now. $privateKey = dirname(__DIR__) . '/cloudfront/my-private-key.pem'; $keyPairId = 'AAPKAJIKZATYYYEXAMPLE'; $cloudFrontClient = new CloudFrontClient([ 'profile' => 'default', 'version' => '2018-06-18', 'region' => 'us-east-1' ]); $result = signCookie( $cloudFrontClient, $resourceKey, $expires, $privateKey, $keyPairId ); /* If successful, returns something like: CloudFront-Expires = 1589926678 CloudFront-Signature = Lv1DyC2q...2HPXaQ__ CloudFront-Key-Pair-Id = AAPKAJIKZATYYYEXAMPLE */ foreach ($result as $key => $value) { echo $key . ' = ' . $value . "\n"; } } // Uncomment the following line to run this code in an AWS account. // signACookie();

创建 CloudFront Cookie 时使用自定义策略

getSignedUrl 相同,您可以提供 'policy' 参数(而不是 expires 参数),以及 url 参数,使用自定义策略针对 Cookie 签名。自定义策略可以在资源键中包含通配符。这样您就可以为多个文件创建一个签名 Cookie。

getSignedCookie 返回的键值对数组均需设置为 Cookie,这样才能为私有分配授予访问权限。

导入

require 'vendor/autoload.php'; use Aws\CloudFront\CloudFrontClient; use Aws\Exception\AwsException;

示例代码

function signCookiePolicy( $cloudFrontClient, $customPolicy, $privateKey, $keyPairId ) { try { $result = $cloudFrontClient->getSignedCookie([ 'policy' => $customPolicy, 'private_key' => $privateKey, 'key_pair_id' => $keyPairId ]); return $result; } catch (AwsException $e) { return [ 'Error' => $e->getAwsErrorMessage() ]; } } function signACookiePolicy() { $resourceKey = 'https://d13l49jEXAMPLE.cloudfront.net/my-file.txt'; $expires = time() + 300; // 5 minutes (5 * 60 seconds) from now. $customPolicy = <<<POLICY { "Statement": [ { "Resource": "{$resourceKey}", "Condition": { "IpAddress": {"AWS:SourceIp": "{$_SERVER['REMOTE_ADDR']}/32"}, "DateLessThan": {"AWS:EpochTime": {$expires}} } } ] } POLICY; $privateKey = dirname(__DIR__) . '/cloudfront/my-private-key.pem'; $keyPairId = 'AAPKAJIKZATYYYEXAMPLE'; $cloudFrontClient = new CloudFrontClient([ 'profile' => 'default', 'version' => '2018-06-18', 'region' => 'us-east-1' ]); $result = signCookiePolicy( $cloudFrontClient, $customPolicy, $privateKey, $keyPairId ); /* If successful, returns something like: CloudFront-Policy = eyJTdGF0...fX19XX0_ CloudFront-Signature = RowqEQWZ...N8vetw__ CloudFront-Key-Pair-Id = AAPKAJIKZATYYYEXAMPLE */ foreach ($result as $key => $value) { echo $key . ' = ' . $value . "\n"; } } // Uncomment the following line to run this code in an AWS account. // signACookiePolicy();

向 Guzzle 客户端发送 CloudFront cookie

您也可以将这些 Cookie 传递至 GuzzleHttp\Cookie\CookieJar,与 Guzzle 客户端结合使用。

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');

有关更多信息,请参阅《亚马逊 CloudFront 开发者指南》中的使用签名 Cookie