El siguiente ejemplo de código es similar al ejemplo de Crear una firma de URL con PHP en el sentido de que crea un enlace a un video. Sin embargo, en lugar de firmar la URL en el código, en este ejemplo se firman las cookies con la función create_signed_cookies()
. El reproductor del cliente utiliza las cookies para autenticar cada solicitud a la distribución de CloudFront.
Este enfoque resulta útil para transmitir contenido, como HTTP Live Streaming (HLS) o la transmisión dinámica adaptativa a través de HTTP (DASH), donde el cliente debe realizar varias solicitudes para recuperar el manifiesto, los segmentos y los activos de reproducción relacionados. Al usar cookies firmadas, el cliente puede autenticar cada solicitud sin necesidad de generar una nueva URL firmada para cada segmento.
nota
-
Crear una firma de URL es solo una parte del proceso de entrega de contenido privado mediante cookies firmadas. Para obtener más información, consulte Uso de cookies firmadas.
En las siguientes secciones, se desglosa el ejemplo de código en partes individuales. A continuación, encontrará el ejemplo de código completo.
Creación de la firma RSA SHA-1
Este ejemplo de código hace lo siguiente:
-
La función
rsa_sha1_sign
proporciona hashes y firma la instrucción de política. Los argumentos requeridos son una instrucción de política y la clave privada que corresponde a una clave pública que está en un grupo de claves de confianza para la distribución. -
A continuación, la función
url_safe_base64_encode
crea una versión de la firma de URL segura.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); }
Creación de cookies firmadas
El siguiente código crea las cookies firmadas con los siguientes atributos de cookie: CloudFront-Expires
, CloudFront-Signature
y CloudFront-Key-Pair-Id
. El código usa una política personalizada.
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
);
}
Para obtener más información, consulte Establecimiento de cookies firmadas mediante una política personalizada.
Código completo
El siguiente ejemplo de código proporciona una demostración completa de la creación de cookies firmadas de CloudFront con PHP. Puede descargar el ejemplo completo desde el archivo demo-php.zip.
En el siguiente ejemplo, puede modificar el elemento $policy Condition
para permitir los rangos de direcciones IPv4 e IPv6. Para ver un ejemplo, consulte Uso de direcciones IPv6 en políticas de IAM en la Guía del usuario de 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 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>
En lugar de utilizar cookies firmadas, puede utilizar URL firmadas. Para obtener más información, consulte Crear una firma de URL con PHP.