View a markdown version of this page

Erstellen signierter Cookies mit PHP - Amazon CloudFront

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Erstellen signierter Cookies mit PHP

Das folgende Codebeispiel ähnelt dem Beispiel aus Erstellen einer URL-Signatur mit PHP insofern, als es einen Link zu einem Video erstellt. Anstatt jedoch die URL im Code zu signieren, signiert dieses Beispiel die Cookies mit der Funktion create_signed_cookies(). Der clientseitige Player verwendet die Cookies, um jede Anfrage an die Distribution zu authentifizieren. CloudFront

Dieser Ansatz ist nützlich, um Inhalte wie HTTP Live Streaming (HLS) oder Dynamic Adaptive Streaming over HTTP (DASH) zu streamen, bei denen der Client mehrere Anforderungen stellen muss, um das Manifest, die Segmente und die zugehörigen Wiedergabe-Assets abzurufen. Mithilfe signierter Cookies kann der Client jede Anforderung authentifizieren, ohne für jedes Segment eine neue signierte URL generieren zu müssen.

Anmerkung
  • Das Erstellen einer URL-Signatur ist nur ein Teil der Bereitstellung privater Inhalte über signierte Cookies. Weitere Informationen finden Sie unter Verwenden signierter Cookies.

In den folgenden Abschnitten wird das Codebeispiel in einzelne Teile unterteilt. Das vollständige Codebeispiel finden Sie unten.

Erstellen Sie die RSA oder Signatur SHA-1 SHA-256

Dieses Codebeispiel führt Folgendes aus:

  1. Die Funktion rsa_sha1_sign hasht und signiert die Richtlinienerklärung mit. SHA-1 Verwenden Sie SHA-256 stattdessen die unten abgebildete Funktion rsa_sha256_sign. Die erforderlichen Argumente sind eine Richtlinienanweisung und der private Schlüssel, der einem öffentlichen Schlüssel entspricht, der sich in einer vertrauenswürdigen Schlüsselgruppe für Ihre Distribution befindet.

  2. Als Nächstes erstellt die url_safe_base64_encode Funktion eine Version der Signatur. URL-safe

    function rsa_sha1_sign($policy, $private_key_filename) { $signature = ""; $fp = fopen($private_key_filename, "r"); $priv_key = fread($fp, 8192); fclose($fp); $pkeyid = openssl_get_privatekey($priv_key); openssl_sign($policy, $signature, $pkeyid); openssl_free_key($pkeyid); return $signature; } function url_safe_base64_encode($value) { $encoded = base64_encode($value); return str_replace( array('+', '=', '/'), array('-', '_', '~'), $encoded); }

    Die folgende Funktion verwendet SHA-256 anstelle von SHA-1:

    function rsa_sha256_sign($policy, $private_key_filename) { $signature = ""; $fp = fopen($private_key_filename, "r"); $priv_key = fread($fp, 8192); fclose($fp); $pkeyid = openssl_get_privatekey($priv_key); openssl_sign($policy, $signature, $pkeyid, OPENSSL_ALGO_SHA256); openssl_free_key($pkeyid); return $signature; }

    Die rsa_sha256_sign Funktion ist dieselbe wiersa_sha1_sign, außer dass sie OPENSSL_ALGO_SHA256 an übergeben wirdopenssl_sign. Wenn Sie es verwenden SHA-256, fügen Sie das CloudFront-Hash-Algorithm Cookie mit einem Wert von hinzuSHA256.

Der folgende Code konstruiert und erstellt die signierten Cookies unter Verwendung der folgenden Cookie-Attribute: CloudFront-ExpiresCloudFront-Signature, CloudFront-Key-Pair-Id undCloudFront-Hash-Algorithm. Der Code verwendet eine benutzerdefinierte Richtlinie.

function create_signed_cookies($resource, $private_key_filename, $key_pair_id, $expires, $client_ip = null, $hash_algorithm = 'SHA1') { $policy = array( 'Statement' => array( array( 'Resource' => $resource, 'Condition' => array( 'DateLessThan' => array('AWS:EpochTime' => $expires) ) ) ) ); if ($client_ip) { $policy['Statement'][0]['Condition']['IpAddress'] = array('AWS:SourceIp' => $client_ip . '/32'); } $policy = json_encode($policy); $encoded_policy = url_safe_base64_encode($policy); if ($hash_algorithm === 'SHA256') { $signature = rsa_sha256_sign($policy, $private_key_filename); } else { $signature = rsa_sha1_sign($policy, $private_key_filename); } $encoded_signature = url_safe_base64_encode($signature); $cookies = array( 'CloudFront-Policy' => $encoded_policy, 'CloudFront-Signature' => $encoded_signature, 'CloudFront-Key-Pair-Id' => $key_pair_id ); if ($hash_algorithm === 'SHA256') { $cookies['CloudFront-Hash-Algorithm'] = 'SHA256'; } return $cookies; }

Weitere Informationen finden Sie unter Einrichten signierter Cookies mit einer benutzerdefinierten Richtlinie.

Vollständiger Code

Der folgende Beispielcode bietet eine vollständige Demonstration der Erstellung CloudFront signierter Cookies mit PHP. Sie können das vollständige Beispiel aus der Datei demo-php.zip herunterladen.

Im folgenden Beispiel können Sie das Element $policy Condition so anpassen, dass sowohl IPv4- und IPv6-Adressbereiche erlaubt sind. Ein Beispiel finden Sie unter Verwenden von IPv6-Adressen in IAM-Richtlinien im Benutzerhandbuch für Amazon Simple Storage Service.

<?php function rsa_sha1_sign($policy, $private_key_filename) { $signature = ""; $fp = fopen($private_key_filename, "r"); $priv_key = fread($fp, 8192); fclose($fp); $pkeyid = openssl_get_privatekey($priv_key); openssl_sign($policy, $signature, $pkeyid); openssl_free_key($pkeyid); return $signature; } function url_safe_base64_encode($value) { $encoded = base64_encode($value); return str_replace( array('+', '=', '/'), array('-', '_', '~'), $encoded); } function rsa_sha256_sign($policy, $private_key_filename) { $signature = ""; $fp = fopen($private_key_filename, "r"); $priv_key = fread($fp, 8192); fclose($fp); $pkeyid = openssl_get_privatekey($priv_key); openssl_sign($policy, $signature, $pkeyid, OPENSSL_ALGO_SHA256); openssl_free_key($pkeyid); return $signature; } function create_signed_cookies($resource, $private_key_filename, $key_pair_id, $expires, $client_ip = null, $hash_algorithm = 'SHA1') { $policy = array( 'Statement' => array( array( 'Resource' => $resource, 'Condition' => array( 'DateLessThan' => array('AWS:EpochTime' => $expires) ) ) ) ); if ($client_ip) { $policy['Statement'][0]['Condition']['IpAddress'] = array('AWS:SourceIp' => $client_ip . '/32'); } $policy = json_encode($policy); $encoded_policy = url_safe_base64_encode($policy); if ($hash_algorithm === 'SHA256') { $signature = rsa_sha256_sign($policy, $private_key_filename); } else { $signature = rsa_sha1_sign($policy, $private_key_filename); } $encoded_signature = url_safe_base64_encode($signature); $cookies = array( 'CloudFront-Policy' => $encoded_policy, 'CloudFront-Signature' => $encoded_signature, 'CloudFront-Key-Pair-Id' => $key_pair_id ); if ($hash_algorithm === 'SHA256') { $cookies['CloudFront-Hash-Algorithm'] = 'SHA256'; } return $cookies; } $private_key_filename = '/home/test/secure/example-priv-key.pem'; $key_pair_id = 'K2JCJMDEHXQW5F'; $base_url = 'https://d1234.cloudfront.net'; $expires = time() + 3600; // 1 hour from now // Get the viewer real IP from the x-forward-for header as $_SERVER['REMOTE_ADDR'] will return viewer facing IP. An alternative option is to use CloudFront-Viewer-Address header. Note that this header is a trusted CloudFront immutable header. Example format: IP:PORT ("CloudFront-Viewer-Address": "1.2.3.4:12345") $client_ip = $_SERVER['HTTP_X_FORWARDED_FOR']; // For HLS manifest and segments (using wildcard) $hls_resource = $base_url . '/sign/*'; $signed_cookies = create_signed_cookies($hls_resource, $private_key_filename, $key_pair_id, $expires, $client_ip, 'SHA256'); // Set the cookies $cookie_domain = parse_url($base_url, PHP_URL_HOST); foreach ($signed_cookies as $name => $value) { setcookie($name, $value, $expires, '/', $cookie_domain, true, true); } ?> <!DOCTYPE html> <html> <head> <title>CloudFront Signed HLS Stream with Cookies</title> </head> <body> <h1>Amazon CloudFront Signed HLS Stream with Cookies</h1> <h2>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?> only viewable by IP <?php echo $client_ip; ?></h2> <div id='hls-video'> <video id="video" width="640" height="360" controls></video> </div> <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> <script> var video = document.getElementById('video'); var manifestUrl = '<?php echo $base_url; ?>/sign/manifest.m3u8'; if (Hls.isSupported()) { var hls = new Hls(); hls.loadSource(manifestUrl); hls.attachMedia(video); } else if (video.canPlayType('application/vnd.apple.mpegurl')) { video.src = manifestUrl; } </script> </body> </html>

Anstelle von signierten Cookies können Sie signierte URLs verwenden. Weitere Informationen finden Sie unter Erstellen einer URL-Signatur mit PHP.