

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用第 3 適用於 PHP 的 AWS SDK 版簽署 Amazon CloudFront URLs
<a name="cloudfront-example-signed-url"></a>

已簽章 URL 可讓您提供使用者存取您的私有內容。已簽署的 URL 包含附加資訊 (例如過期時間)，以便您更有效地控制對內容的存取。此附加資訊顯示在政策聲明中，該政策聲明基於標準政策或自訂政策。如需有關如何設定私有分佈以及為什麼您需要簽署 URLs的資訊，請參閱《[Amazon CloudFront 開發人員指南》中的透過 Amazon CloudFront 提供私有內容](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html)。 Amazon CloudFront 
+ 使用 [getSignedURL](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.CloudFront.CloudFrontClient.html#_getSignedUrl) 建立已簽署的 Amazon CloudFront URL。
+ 使用 [getSignedCookie](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.CloudFront.CloudFrontClient.html#_getSignedCookie) 建立已簽署的 Amazon CloudFront cookie。

您可以在 GitHub 上 適用於 PHP 的 AWS SDK 取得 的所有範例程式碼。 [ GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code)

## 憑證
<a name="examplecredentials"></a>

在執行範例程式碼之前，請先設定您的 AWS 登入資料，如中所述[AWS 使用第 3 適用於 PHP 的 AWS SDK 版向 驗證](credentials.md)。然後匯入 適用於 PHP 的 AWS SDK，如 中所述[安裝第 3 適用於 PHP 的 AWS SDK 版](getting-started_installation.md)。

如需使用 Amazon CloudFront 的詳細資訊，請參閱 [Amazon 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 簽章的 URL
<a name="use-a-cf-signed-url"></a>

簽署 URL 的形式各有不同，取決於您要簽署的 URL 是使用「HTTP」還是「RTMP」機制。如果是「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>

做為已簽章的 URL 替代方案，您還可以授予用戶端透過已簽章的 cookie 存取私有分發權限。已簽章的 cookie 可讓您提供對多個限制檔案的存取，例如 HLS 格式視訊的所有檔案或網站中訂閱者區域的所有檔案。如需為何您可能想要使用已簽章的 Cookie 而非已簽章URLs 的詳細資訊 （反之亦然），請參閱《Amazon CloudFront 開發人員指南》中的[選擇已簽章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`，您可以透過自訂政策簽署 cookie 以提供 `'policy'` 參數，而非 `expires` 參數與 `url` 參數。自訂政策可以包含在資源金鑰中的萬用字元。這可讓您建立多個檔案的單一簽章 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();
```

## 將 CloudFront Cookie 傳送至 Guzzle 用戶端
<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');
```

如需詳細資訊，請參閱《Amazon CloudFront 開發人員指南》中的[使用已簽章的 Cookie](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html)。