簡體   English   中英

PHP - 使用 REST API 從 AWS S3 中刪除 object

[英]PHP - Delete object from AWS S3 with REST API

我正在嘗試使用 REST API 從亞馬遜 s3 中刪除 object。我創建了一個 curl 命令,但出現 403 錯誤:“SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided”。

我在 AWS 文檔中使用: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header基於-auth.html

這是我的代碼:

$host = 's3.amazonaws.com';
$url = "https://" . $bucket . '.' . $host . '/' . $file;
$date_full = date('D, d M Y H:i:s \G\M\T');
$date = date('Ymd');
$longDate = gmdate('Ymd\THis\Z');
$shortDate = gmdate('Ymd');
$credential = $accessKeyId . '/' . $shortDate . '/' . $region . '/s3/aws4_request';
$hashed_payload = strtolower(hash("sha256", ""));

$headers = [
    'X-Amz-Algorithm' => 'AWS4-HMAC-SHA256',
    'X-Amz-Credential' => $credential,
    'X-Amz-Date' => $longDate,
    'X-Amz-Expires' => 86400,
    'X-Amz-SignedHeaders' => 'host',
    'x-amz-content-sha256' => $hashed_payload,
    'Host' => $bucket . '.' . $host,
];
ksort($headers);
$signed_headers_string = strtolower(implode(';', array_keys($headers)));

// Build canonical request
$canonical_request = "DELETE\n"; // HTTPRequestMethod
$canonical_request .= '/' . urlencode("http://s3.amazonaws.com/" . $bucket . "/" . $file) . "\n"; // CanonicalURI
$canonical_request .= "\n"; // CanonicalQueryString

foreach ($headers as $header => $value) {
    $canonical_request .= strtolower($header) . ':' . trim($value) . "\n"; //CanonicalHeaders
}

$canonical_request .= $signed_headers_string . "\n"; // SignedHeaders
$canonical_request .= $hashed_payload; // HashedPayload

// Build string to sign
$string_to_sign = "AWS4-HMAC-SHA256\n";
$string_to_sign .= $date_full . "\n";
$string_to_sign .= $date . '/' . $region. "/s3/aws4_request\n";
$string_to_sign .= hash('sha256', $canonical_request);

// Calculate signature
$signature_date = hash_hmac('sha256', $date, 'AWS4' . $secretKey, true);
$signature_region = hash_hmac('sha256', $region, $signature_date, true);
$signature_service = hash_hmac('sha256', 's3', $signature_region, true);
$signature_request = hash_hmac('sha256', 'aws4_request', $signature_service, true);

// Build Signature
$signature = hash_hmac('sha256', $string_to_sign, $signature_request);

// Calculate final Authorization header
$headers['Authorization'] = 'AWS4-HMAC-SHA256 Credential=' . $credential . ', ';
$headers['Authorization'] .= 'SignedHeaders=' . $signed_headers_string . ', ';
$headers['Authorization'] .= 'Signature=' . $signature;

// Convert headers to key:value strings
$curl_headers = array();

foreach ($headers as $header => $value) {
    $curl_headers[] = "{$header}:{$value}";
}

// Init curl
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $curl_headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");

$result = curl_exec($curl);

有人可以幫助我了解問題所在嗎?

您正在對具有大寫和小寫字母的鍵進行排序。 在調用ksort()之前,在鍵中使用所有小寫字母。

您還包括不需要包含的標頭。 您提到的文檔只要求提供x-amz-datex-amz-content-sha256host 僅使用那些標頭。

$headers = [
    'x-amz-date' => $longDate,
    'x-amz-content-sha256' => $hashed_payload,
    'host' => $bucket . '.' . $host,
];
ksort($headers);

添加標頭后,您的規范請求應該有一個額外的換行符:

foreach ($headers as $header => $value) {
    $canonical_request .= strtolower($header) . ':' . trim($value) . "\n"; //CanonicalHeaders
}
$canonical_request .= "\n";

我不確定是否需要進行此更改,但在 $string_to_sign 中,我使用 $longDate 提供的日期格式,而不是 $date_full:

// Build string to sign
$string_to_sign = "AWS4-HMAC-SHA256\n";
$string_to_sign .= $longDate . "\n";
$string_to_sign .= $date . '/' . $region. "/s3/aws4_request\n";
$string_to_sign .= hash('sha256', $canonical_request);

您正在設置CURLOPT_CUSTOMREQUEST兩次,首先是PUT ,然后是DELETE 最后一個設置可能是正在使用的設置,但我會刪除curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); 為清楚起見。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM