简体   繁体   English

没有sdk的php s3预签名网址

[英]php s3 pre signed url without sdk

I'm using this class to generate a direct upload form which includes the policy part.我正在使用这个类来生成一个包含策略部分的直接上传表单。

https://www.designedbyaturtle.co.uk/2015/direct-upload-to-s3-using-aws-signature-v4-php/ https://www.designedbyaturtle.co.uk/2015/direct-upload-to-s3-using-aws-signature-v4-php/

The uploads are working but I want to be able to display the file from the url for users on the site without making the files public.上传工作正常,但我希望能够在不公开文件的情况下为网站上的用户显示来自 url 的文件。

I understand the SDK has a simple method for this but I am hoping I can do it with the existing code as this already creates the policy.我知道 SDK 有一个简单的方法,但我希望我可以使用现有代码来完成,因为这已经创建了策略。 I'm wondering what are hte steps for creating this url from scratch?我想知道从头开始创建这个 url 的步骤是什么? It seems excessive to include the entire bloated SDK for just one function.将整个臃肿的 SDK 仅包含一个功能似乎有些过分。

I solved it by using these two classes and modifying them a bit to make a class with two functions geturl and getform instead of using the API, these work great for v4 signatures.我通过使用这两个类并稍微修改它们以创建一个具有两个函数 geturl 和 getform 而不是使用 API 的类来解决它,这些对于 v4 签名非常有用。

getform:获取形式:

https://www.designedbyaturtle.co.uk/2015/direct-upload-to-s3-using-aws-signature-v4-php/ https://www.designedbyaturtle.co.uk/2015/direct-upload-to-s3-using-aws-signature-v4-php/

geturl:获取网址:

https://gist.github.com/anthonyeden/4448695ad531016ec12bcdacc9d91cb8 https://gist.github.com/anthonyeden/4448695ad531016ec12bcdacc9d91cb8

Creating an S3 pre-signed URL is actually very easy for GET requests.对于 GET 请求,创建 S3 预签名 URL 实际上非常容易。 PUT is fairly easy, but POST is complicated and requires a policy. PUT 相当容易,但 POST 很复杂并且需要策略。

The challenge is creating the signing code.挑战在于创建签名代码。 Amazon supports two versions v2 and v4.亚马逊支持 v2 和 v4 两个版本。 v2 is being phased out. v2 正在逐步淘汰。 v4 is somewhat complicated to code. v4 的编码有些复杂。

If you are only creating pre-signed URLs for GET requests, write your own code.如果您只是为 GET 请求创建预签名 URL,请编写您自己的代码。 For anything else, I seriously recommend using the SDK.对于其他任何事情,我强烈建议使用 SDK。

Below is a link to the source code to pre-sign an S3 URL using S3V4 using PHP without the AWS SDK.下面是源代码的链接,用于使用 S3V4 使用 PHP 预签名 S3 URL,无需 AWS 开发工具包。

S3LINK-V4.PHP S3LINK-V4.PHP

I wrote a function in php using @xmxmxmx answer and it is working fine with me我使用@xmxmxmx 答案在 php 中编写了一个函数,它对我来说很好用

function AWS_S3_PresignDownload($AWSAccessKeyId, $AWSSecretAccessKey, $BucketName, $AWSRegion, $canonical_uri, $expires = 8400)
{
    $encoded_uri = str_replace('%2F', '/', rawurlencode($canonical_uri));
    // Specify the hostname for the S3 endpoint
    if ($AWSRegion == 'us-east-1') {
        $hostname = trim($BucketName . ".s3.amazonaws.com");
        $header_string = "host:" . $hostname . "\n";
        $signed_headers_string = "host";
    } else {
        $hostname =  trim($BucketName . ".s3-" . $AWSRegion . ".amazonaws.com");
        $header_string = "host:" . $hostname . "\n";
        $signed_headers_string = "host";
    }

    $currentTime = time();
    $date_text = gmdate('Ymd', $currentTime);

    $time_text = $date_text . 'T' . gmdate('His', $currentTime) . 'Z';
    $algorithm = 'AWS4-HMAC-SHA256';
    $scope = $date_text . "/" . $AWSRegion . "/s3/aws4_request";

    $x_amz_params = array(
        'X-Amz-Algorithm' => $algorithm,
        'X-Amz-Credential' => $AWSAccessKeyId . '/' . $scope,
        'X-Amz-Date' => $time_text,
        'X-Amz-SignedHeaders' => $signed_headers_string
    );

    // 'Expires' is the number of seconds until the request becomes invalid
    $x_amz_params['X-Amz-Expires'] = $expires + 30; // 30seocnds are less
    ksort($x_amz_params);

    $query_string = "";
    foreach ($x_amz_params as $key => $value) {
        $query_string .= rawurlencode($key) . '=' . rawurlencode($value) . "&";
    }
    
    $query_string = substr($query_string, 0, -1);

    $canonical_request = "GET\n" . $encoded_uri . "\n" . $query_string . "\n" . $header_string . "\n" . $signed_headers_string . "\nUNSIGNED-PAYLOAD";
    $string_to_sign = $algorithm . "\n" . $time_text . "\n" . $scope . "\n" . hash('sha256', $canonical_request, false);

    $signing_key = hash_hmac('sha256', 'aws4_request', hash_hmac('sha256', 's3', hash_hmac('sha256', $AWSRegion, hash_hmac('sha256', $date_text, 'AWS4' . $AWSSecretAccessKey, true), true), true), true);

    $signature = hash_hmac('sha256', $string_to_sign, $signing_key);
    return 'https://' . $hostname . $encoded_uri . '?' . $query_string . '&X-Amz-Signature=' . $signature;
}

Call it using调用它使用

echo AWS_S3_PresignDownload('accessId', 'seceret', 's3BucketName', 'reGion', '/fileKey.ext', 60);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM