Php 如何为AWS S3上的内容生成过期URL

Php 如何为AWS S3上的内容生成过期URL,php,amazon-s3,Php,Amazon S3,我想创建一个临时URL,供用户从我的aws s3 bucket下载内容。有没有关于如何快速轻松地完成这项工作的教程?我将php用于服务器端代码一种方法是使用对称加密函数(如mcrypt_encrypt)加密当前日期和时间。然后,加密文本作为查询字符串附加到URL http://hostname.domain.tld/path/to/validationscript.php?FsUBxPBe88SFu1wlJav8Wk23nnyGfdi%2FP4p95lK7DuErfjGDhUB8%2B1G02W

我想创建一个临时URL,供用户从我的aws s3 bucket下载内容。有没有关于如何快速轻松地完成这项工作的教程?我将php用于服务器端代码

一种方法是使用对称加密函数(如mcrypt_encrypt)加密当前日期和时间。然后,加密文本作为查询字符串附加到URL

http://hostname.domain.tld/path/to/validationscript.php?FsUBxPBe88SFu1wlJav8Wk23nnyGfdi%2FP4p95lK7DuErfjGDhUB8%2B1G02WeDqfb8krFjo5ABNRlcTwTs7eNDAzh2ixPsBFUqZWYaRyOQHDaEiuHA0SLpZVQH8SAnnGiQ%7C3LmPuTeozYqr3HhMIGC%2FoBM2Kd6qfb81LYgPZjmgpC8%3D
然后,当访问URL时,URL的目标脚本解密查询字符串,以获取创建链接的日期和时间,并将其与当前日期和时间进行比较。如果超过允许的时间间隔,则该链接被视为无效

这是创建过期链接的脚本:

        <?
        define('ENCRYPTION_KEY', '9ab6c9abcd827e8726f92275f87e7abc820937d87e871c85e982d8eb08ba87ef');  // this is super-secret.  don't let it get out!
        $expiration=300;  //link expires in 300 seconds

        $expirationtime=time()+$expiration;
        //print $expirationtime;
        $URL="http://hostname.domain.tld/path/to/validationscript.php?" . urlencode(mc_encrypt($expirationtime, ENCRYPTION_KEY));
        print "Link is: <BR>" . $URL . "<BR><BR>Please note that this link is valid only for " . $expiration . " seconds.";


        // Encrypt Function
        function mc_encrypt($encrypt, $key){
            $encrypt = serialize($encrypt);
            $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
            $key = pack('H*', $key);
            $mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
            $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
            $encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
            return $encoded;
        }
        ?>
即将过期的链接指向下面的验证脚本,该脚本检查链接是否仍然有效:

            <?
            define('ENCRYPTION_KEY', '9ab6c9abcd827e8726f92275f87e7abc820937d87e871c85e982d8eb08ba87ef');  // this is super-secret.  don't let it get out!

            $expirationtime=mc_decrypt(urldecode($_SERVER['QUERY_STRING']), ENCRYPTION_KEY);
            if(time()<$expirationtime) {
                print "link is still valid.<BR>";
            } else {
                print "link is no longer valid.<BR>";
            }


            // Decrypt Function
            function mc_decrypt($decrypt, $key){
                $decrypt = explode('|', $decrypt);
                $decoded = base64_decode($decrypt[0]);
                $iv = base64_decode($decrypt[1]);
                $key = pack('H*', $key);        
                $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
                $mac = substr($decrypted, -64);
                $decrypted = substr($decrypted, 0, -64);
                $calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
                if($calcmac!==$mac){ return false; }
                $decrypted = unserialize($decrypted);
                return $decrypted;
            }

            ?>

此功能内置于S3及其PHP SDK中


当然我编辑我的答案是为了提供一个工作示例。当S3 SDK本机仅在几行代码中支持过期链接时,为什么会这样做?版本3:
// Get a pre-signed URL for an Amazon S3 object
// $client is an instance of AWS SDK's S3Client
$signedUrl = $client->getObjectUrl('my-bucket', 'filename.ext', '+10 minutes');
// > https://my-bucket.s3.amazonaws.com/filename.ext?AWSAccessKeyId=[...]&Expires=[...]&Signature=[...]