PHP를 사용하여 서명된 쿠키 생성
다음 코드 예제는 동영상에 대한 링크를 만드는 PHP를 사용한 URL 서명 생성의 예제와 유사합니다. 그러나 이 예제에서는 코드의 URL에 서명하는 대신 create_signed_cookies()
함수를 사용하여 쿠키에 서명합니다. 클라이언트 측 플레이어는 쿠키를 사용하여 CloudFront 배포에 대한 각 요청을 인증합니다.
이 접근 방식은 클라이언트가 매니페스트, 세그먼트 및 관련 재생 자산을 검색하기 위해 여러 요청을 해야 하는 HLS(HTTP Live Streaming) 또는 DASH(Dynamic Adaptive Streaming over HTTP)와 같은 콘텐츠를 스트리밍하는 데 유용합니다. 클라이언트는 서명된 쿠키를 사용하여 각 세그먼트에 대해 서명된 새 URL을 만들 필요 없이 각 요청을 인증할 수 있습니다.
참고
-
URL 서명을 만드는 것은 서명된 쿠키를 사용해 프라이빗 콘텐츠를 제공하는 프로세스의 한 부분에 불과합니다. 자세한 내용은 서명된 쿠키 사용 섹션을 참조하세요.
다음 섹션에서는 코드 예제를 각 부분으로 나눕니다. 아래에서 전체 코드 샘플을 확인할 수 있습니다.
RSA SHA-1 서명 생성
이 코드 예제에서는 다음을 수행합니다.
-
rsa_sha1_sign
함수는 정책 문을 해시하고 서명합니다. 필요한 인수는 배포의 신뢰할 수 있는 키 그룹에 있는 퍼블릭 키에 해당하는 프라이빗 키와 정책 설명입니다. -
다음으로
url_safe_base64_encode
함수는 서명의 안전한 URL 버전을 만듭니다.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); }
서명된 쿠키 생성
다음 코드는 다음 쿠키 속성(예: CloudFront-Expires
, CloudFront-Signature
, CloudFront-Key-Pair-Id
)을 사용하여 서명된 쿠키를 만듭니다. 코드는 사용자 지정 정책을 사용합니다.
function create_signed_cookies($resource, $private_key_filename, $key_pair_id, $expires, $client_ip = null) { $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); $signature = rsa_sha1_sign($policy, $private_key_filename); $encoded_signature = url_safe_base64_encode($signature); return array( 'CloudFront-Policy' => $encoded_policy, 'CloudFront-Signature' => $encoded_signature, 'CloudFront-Key-Pair-Id' => $key_pair_id ); }
자세한 내용은 사용자 지정 정책을 사용하여 서명된 쿠키 설정 섹션을 참조하세요.
전체 코드
다음 예제 코드는 PHP로 CloudFront 서명 쿠키를 만드는 전체 데모를 제공합니다. demo-php.zip 파일에서 전체 예제를 다운로드할 수 있습니다.
다음 예제에서는 IPv4 및 IPv6 주소 범위를 모두 허용하도록 $policy Condition
요소를 수정할 수 있습니다. 예제는 Amazon Simple Storage Service 사용 설명서의 IAM 정책에서 IPv6 주소 사용을 참조합니다.
<?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 create_signed_cookies($resource, $private_key_filename, $key_pair_id, $expires, $client_ip = null) { $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); $signature = rsa_sha1_sign($policy, $private_key_filename); $encoded_signature = url_safe_base64_encode($signature); return array( 'CloudFront-Policy' => $encoded_policy, 'CloudFront-Signature' => $encoded_signature, 'CloudFront-Key-Pair-Id' => $key_pair_id ); } $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); // 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>
서명된 쿠키를 사용하는 대신 서명된 URL을 사용할 수 있습니다. 자세한 내용은 PHP를 사용한 URL 서명 생성 섹션을 참조하세요.