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

时间:2014-11-18 19:40:28

标签: php amazon-s3

我想为用户创建一个临时URL,以便从我的aws s3存储桶中下载内容。是否有关于如何快速轻松地完成此操作的教程?我使用php作为我的服务器端代码

2 个答案:

答案 0 :(得分:5)

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

http://docs.aws.amazon.com/aws-sdk-php/guide/latest/service-s3.html#creating-a-pre-signed-url

// 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=[...]

答案 1 :(得分:-1)

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

然后,当访问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;
        }
        ?>

上述脚本将生成的链接看起来像这样,其中过期被加密并填充在查询字符串中。

http://hostname.domain.tld/path/to/validationscript.php?FsUBxPBe88SFu1wlJav8Wk23nnyGfdi%2FP4p95lK7DuErfjGDhUB8%2B1G02WeDqfb8krFjo5ABNRlcTwTs7eNDAzh2ixPsBFUqZWYaRyOQHDaEiuHA0SLpZVQH8SAnnGiQ%7C3LmPuTeozYqr3HhMIGC%2FoBM2Kd6qfb81LYgPZjmgpC8%3D

过期链接指向下面的验证脚本,该脚本检查链接是否仍然有效:

            <?
            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;
            }

            ?>