

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

# CloudFront URLs 使用 适用于 PHP 的 AWS SDK 版本 3 签署亚马逊
<a name="cloudfront-example-signed-url"></a>

 URLs 通过签名，您可以向用户提供访问您的私有内容的权限。签名 URL 中包含的其他信息（例如，到期时间）可让您更好地控制对内容的访问。该额外信息出现在策略声明中，且是基于标准策略或自定义策略。有关如何设置私有分配以及为什么需要签署的信息 URLs，请参阅《亚马逊 CloudFront 开发者指南》 CloudFront中的[通过亚马逊提供私有内容](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html)。
+ 使用 [getSigne](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.CloudFront.CloudFrontClient.html#_getSignedUrl) Durl 创建已签名的亚马逊 CloudFront URL。
+ 使用创建已签名的亚马逊 CloudFront Cookie [getSignedCookie](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.CloudFront.CloudFrontClient.html#_getSignedCookie)。

的所有示例代码都可以在[此 适用于 PHP 的 AWS SDK 处找到 GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code)。

## 凭据
<a name="examplecredentials"></a>

在运行示例代码之前，请配置您的 AWS 证书，如中所述[AWS 使用 适用于 PHP 的 AWS SDK 版本 3 进行身份验证](credentials.md)。然后导入 适用于 PHP 的 AWS SDK，如中所述[安装 适用于 PHP 的 AWS SDK 版本 3](getting-started_installation.md)。

有关使用亚马逊的更多信息 CloudFront，请参阅[亚马逊 CloudFront 开发者指南](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/)。

## 签署私 CloudFront URLs 有发行版
<a name="signing-cf-urls-for-private-distributions"></a>

您可以使用 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 URLs
<a name="use-a-custom-policy-when-creating-cf-urls"></a>

要使用自定义策略，请提供 `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 签名网址
<a name="use-a-cf-signed-url"></a>

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

以下示例说明如何使用签名 URL 来构造显示视频的网页[JWPlayer](http://www.longtailvideo.com/jw-player/)。相同类型的技术也适用于其他玩家 [FlowPlayer](http://flowplayer.org/)，例如，但需要不同的客户端代码。

```
<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
<a name="signing-cf-cookies-for-private-distributions"></a>

作为已签名的替代方案 URLs，您还可以通过签名 Cookie 向客户授予访问私有分发的权限。借助经过签名的 Cookie，您可以提供对多个受限文件的访问权限，例如 HLS 格式视频的所有文件，或在网站订阅者区域中的所有文件。要详细了解为何要使用签名 Cookie 而不是签名 URLs （反之亦然），请参阅《亚马逊 CloudFront 开发者指南》中的在[签名 Cookie URLs 和签名 Cookie 之间进行选择](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-choosing-signed-urls-cookies.html)。

创建签名 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 时使用自定义策略
<a name="use-a-custom-policy-when-creating-cf-cookies"></a>

与 `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
<a name="send-cf-cookies-to-guzzle-client"></a>

您也可以将这些 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](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html)。