【问题标题】:Cannot download file with presigned url to remote server using curl无法使用 curl 将带有预签名 url 的文件下载到远程服务器
【发布时间】:2021-09-13 18:00:06
【问题描述】:

我有一个关于使用 AWS S3 预签名 URL 将文件下载到远程服务器的问题。我能够成功地为 zip 文件创建预签名 URL。如果我在浏览器中输入预签名的 URL,我可以成功下载 zip 文件。但是,我还需要我们用户的站点来获取该 zip 文件,将其下载到他们的服务器并解压缩。所以我所做的是使用 PHP CURL 并为 CURLOPT_URL 参数提供了预签名的 URL。但是,当我这样做时,zip 文件是空的,并且我收到一条错误消息。由于我使用的是预签名的 url,它已经具有下载文件所需的授权和签名标头。我的问题是为什么它不能在 PHP CURL 中工作,而只能在浏览器中工作?我在这里没有做什么?

预签名 URL 示例: https://xxxxxxx-xxxxxxxxxx-xxxxxxx-231481972270.s3-accesspoint.us-east-1.amazonaws.com/serenity-pro/serenity-pro.zip?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATLZLGSYXEHERUI4Z%2F20210913%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210913T042133Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Signature=62ba2cb3d434f8643cd5099b74523234df46b3c9fdb0f5ab75d962c8ab4d0428

我的代码:

// Download zip file
// The $download_url is the presigned URL I generated for the user
$ch = curl_init();
$fp = fopen($theme_zip_path, "w+");
curl_setopt_array($ch, array(
CURLOPT_URL => $download_url,
CURLOPT_TIMEOUT => 600,
CURLOPT_FILE => $fp
));
$contents = curl_exec($ch);
curl_close($ch);
fclose($fp);

错误信息: InvalidRequest 不支持您提供的授权机制。请使用签名版本 4

【问题讨论】:

    标签: php amazon-web-services amazon-s3 php-curl


    【解决方案1】:

    如果您的网址包含 https,请尝试添加此内容

    CURLOPT_SSL_VERIFYHOST

    CURLOPT_SSL_VERIFYPEER

    curl_setopt_array($ch, array(
    CURLOPT_URL => $download_url,
    
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_SSL_VERIFYPEER => false,
    
    CURLOPT_TIMEOUT => 600,
    CURLOPT_FILE => $fp
    ));
    
    

    【讨论】:

    • 感谢您的建议 - 我试过了,但仍然得到相同的结果和错误消息。
    【解决方案2】:

    如果有人遇到同样的问题,解决方案是使用 CloudFront 签名的 URL。

    https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreateURL_PHP.html

    // Create a CF signed URL
    use Aws\CloudFront\CloudFrontClient;
    
    $resourceKey = $cloudfront_url;
    $expires = time() + 1800;
    $privateKey = 'YOURPRIVATEKEY.pem';
    $keyPairId = 'YOURKEYPAIRID';
    
    $cfClient = new Aws\CloudFront\CloudFrontClient([
        'version' => 'latest',
        'region' => 'YOURREGION',
        'credentials' => $credentials
    ]);
    
    $download_url = $cfClient->getSignedUrl([
        'url' => $resourceKey,
        'expires' => $expires,
        'private_key' => $privateKey,
        'key_pair_id' => $keyPairId
    ]);
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
    猜你喜欢
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 2015-10-13
    • 2018-12-27
    • 1970-01-01
    相关资源
    最近更新 更多