【问题标题】:PHP AWS api raw request to PUT bucket lifecycle对 PUT 存储桶生命周期的 PHP AWS api 原始请求
【发布时间】:2017-03-09 10:18:20
【问题描述】:

我正在创建一个网站,其中有一个功能,如果用户删除图像/视频,它将被存档,我使用 AWS S3 进行存储,删除时想要将其移动到 Glacier,我不想使用AWS SDK,所以我正在使用 PHP cURL 创建原始请求,从这个链接我尝试将存储桶生命周期放在一个对象上,http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html 并完成了一些代码,但它给了我不匹配签名的错误,

SignatureDoesNotMatch-The request signature we calculated does not match the signature you provided. Check your key and signing method.

这是我的代码,在此我想在存储桶内的x.php 上应用生命周期,应用生命周期使其过期,我做错了什么?帮帮我,

$AWSaccessKey = 'xxxxxxxxxxxxxxxx';
$AWSsecretKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
$AWSregion = 'xxxxxxxxx';

// bucket
$bucket   = 'xxxxxxxx';
$postdata = $filedata = '<LifecycleConfiguration>
  <Rule>
    <Filter>
      <Prefix>/</Prefix>
    </Filter>
    <Status>Enabled</Status>
    <Expiration>
      <Days>0</Days>
    </Expiration>
  </Rule>
</LifecycleConfiguration>';
$filetype = 'text/plain';
$path     = '/x.php'; // file on which i want to put lifecycle to move it to GLACIER

// file md5
$file_md5 = base64_encode(md5($filedata, true));

// file size
$filesize = strlen($filedata);

// date
$date = gmdate('D, d M Y H:i:s').' +0000';

// -> for putting lifecycle config
$params = array(
    'x-amz-date'          => gmdate('D, d M Y H:i:s \\G\\M\\T'),
);
//'x-amz-security-token'=> $auth['Token']

// sort and stringify params (different to other requests, this is formatted like headers)
$params_str = '';
uksort($params, 'strcmp');
foreach($params as $k=>$v){
    $params_str .= $k.': '.$v."\\n";
}

// -> for putting lifecycle config
$to_sign = "PUT\\n$file_md5\\n$filetype\\n\\n".$params_str.'/'.$bucket.$path;

// create signature
// Note: S3 uses SHA1 instead of 256!
$signature = base64_encode(hash_hmac('SHA1', $to_sign, $AWSsecretKey, true));

$headers = "Host: $bucket.s3.amazonaws.com\\n"; // change to your region
$headers .= $params_str;  // note that the params get added to the header
$headers .= 'Content-MD5: '.$file_md5."\\n";
$headers .= 'Authorization: AWS '.$AWSaccessKey.':'.$signature."\\n";
$headers .= 'Content-Length: '.$filesize."\\n";

$ch = curl_init("http://$bucket.s3-$AWSregion.amazonaws.com");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, explode('\n', $headers));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, fopen(dirname(__FILE__).'/errorlog.txt', 'w'));

$result = curl_exec($ch); 
var_dump($result);

【问题讨论】:

  • 在特定路径上定义永久生命周期规则可能更容易(例如s3::bucket/archive/)。然后,将文件移动到该路径以将其存档。 (当然,没有“移动”,它实际上会涉及复制和删除。)

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


【解决方案1】:

我认为您并不完全了解生命周期策略的工作原理。

$path = '/x.php'; // file on which i want to put lifecycle to move it to GLACIER

您不会移动单个文件。您配置前缀。 这应该在您的 XML 文档中。 你已经有了这个

&lt;Prefix&gt;/&lt;/Prefix&gt;

  1. PUT 生命周期应始终为/?lifecycle。你把它写成/x.php
  2. 使用 AWS Signature V4 可能比 V2 更好,因为一些较新的区域不支持 Signature V2,但所有区域都支持 Signature V4。更多信息在这里:http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
  3. 使用 Signature V4,即使您确实看到错误消息 SignatureDoesNotMatch,您也应该看到其他消息,&lt;StringToSignBytes&gt;&lt;/StringToSignBytes&gt;&lt;CanonicalRequest&gt;&lt;/CanonicalRequest&gt;。这些应该足以让您隔离和解决此问题。
  4. 您提到要将其移至 GLACIER,但您没有在 XML 内容中提及这一点。请参阅此页面上的“示例 1:添加生命周期配置 - 未启用版本控制的存储桶”部分以获取 http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html 您的 XML 中需要 &lt;StorageClass&gt;GLACIER&lt;/StorageClass&gt;

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2023-03-11
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多