2016-08-10 125 views
0

我想通過預先簽名的url將文件上傳到aws s3。我使用這個github項目https://github.com/JoernBerkefeld/s3SignedUpload,但它顯示上傳時出錯。aws s3簽名不匹配-pre signed url

<Error> 
<Code>SignatureDoesNotMatch</Code> 
<Message> 
The request signature we calculated does not match the signature you provided. Check your key and signing method. 
</Message> 
<AWSAccessKeyId>AKIAI2DLTCOXU5255TMQ</AWSAccessKeyId> 
<StringToSign> 
AWS4-HMAC-SHA256 20160810T174345Z 20160810/ap-south-1/s3/aws4_request a63f9ead869c1fb4d06fa1169458b87978d86fd44348144636c2e0cb2c10cdf5 
</StringToSign> 
<SignatureProvided> 
ae7bd98265316de85f3c55e539ca9bdb5934620428a7924b9404a9403dd9d4d2 
</SignatureProvided> 
<StringToSignBytes> 
41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 31 36 30 38 31 30 54 31 37 34 33 34 35 5a 0a 32 30 31 36 30 38 31 30 2f 61 70 2d 73 6f 75 74 68 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 61 36 33 66 39 65 61 64 38 36 39 63 31 66 62 34 64 30 36 66 61 31 31 36 39 34 35 38 62 38 37 39 37 38 64 38 36 66 64 34 34 33 34 38 31 34 34 36 33 36 63 32 65 30 63 62 32 63 31 30 63 64 66 35 
</StringToSignBytes> 
<CanonicalRequest> 
GET /logo.jpg Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAI2DLTCOXU5255TMQ%2F20160810%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Date=20160810T174345Z&X-Amz-Expires=1800&X-Amz-SignedHeaders=Host host:indiastreetz.s3.ap-south-1.amazonaws.com host UNSIGNED-PAYLOAD 
</CanonicalRequest> 
<CanonicalRequestBytes> 
47 45 54 0a 2f 6c 6f 67 6f 2e 6a 70 67 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3d 69 6d 61 67 65 25 32 46 6a 70 65 67 26 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 41 4b 49 41 49 32 44 4c 54 43 4f 58 55 35 32 35 35 54 4d 51 25 32 46 32 30 31 36 30 38 31 30 25 32 46 61 70 2d 73 6f 75 74 68 2d 31 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 31 36 30 38 31 30 54 31 37 34 33 34 35 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 31 38 30 30 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 48 6f 73 74 0a 68 6f 73 74 3a 69 6e 64 69 61 73 74 72 65 65 74 7a 2e 73 33 2e 61 70 2d 73 6f 75 74 68 2d 31 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 0a 0a 68 6f 73 74 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44 
</CanonicalRequestBytes> 
<RequestId>78A21E02C733E895</RequestId> 
<HostId> 
rBd5ZQBuMyjouFZbSavDcFX4n4fEuqSj8aZuCQyw9rChSSpZkBFZjd8CXqog2OWPMX96OSIuFmo= 
</HostId> 
</Error> 

解決方案我發現在stackoverflow不能解決我的解決方案。請告訴我如何解決或在哪裏可以找到錯誤。

public function getSignedUrl($filename, $mime) { 
     if(!$filename) { 
      return $this->error('filename missing'); 
     }  
     if(!$mime) {  
      return $this->error('mime-type missing');  
     }  
     $final_filename = $this->get_file_name($filename);   
     try {  
      $signedUrl = $this->client->getCommand('PutObject', array( 
       'Bucket' => $this->bucket,  
       'Key' => $this->folder.$final_filename,  
       'ContentType' => $mime,  
       'Body'  => '',  
       'ContentMD5' => false  
      ))->createPresignedUrl('+30 minutes');  
     } catch (S3Exception $e) {  
      echo $e->getMessage() . "\n";  
     }  

     $signedUrl .= '&Content-Type='.urlencode($mime); 
     return array('url'=>$signedUrl); 
    } 
+0

你用什麼方法來登錄的網址? – McStuffins

+0

實際上我不用我自己的方法來簽名。$ signedUrl = $ s3Upload-> getSignedUrl($ filename,$ mime);我爲此使用了Aws庫。 – Raj

+0

你能找到該功能並將其發佈在你的問題中嗎? – McStuffins

回答

0

我使用PHP內置散列函數預先簽名上傳,然後用POST上傳文件。

當用戶點擊上傳按鈕時,它會從presign_url獲得一個預先簽署的數據,然後開始上傳到aws。

$.ajax({ 
       url: 'presign_url.php', 
       type: 'post', 
       dataType: 'json', 
       success: function (data) { 
        send_img(png,image_size,data); /* append this data with your post data. I pass the data to my image uploading function.data contains presigned data(image name,file size,format and other amazon credentials)*/ 
       }, 
       data: {} 
      }); 

//presign_url.php

<?php 
    $access_key   = "XXXXXXXXXXXX"; //Access Key 
    $secret_key   = "xyzxyzxyzxyz"; //Secret Key 
    $my_bucket   = "bucketname"; //bucket name 
    $region    = "your region"; //bucket region ex:-ap-south-1 
    $success_redirect = "http://localhost/info";// your redirect url 
    $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']; //URL to which the client is redirected upon success (currently self) 
    $allowd_file_size = "1048579"; //1 MB allowed Size 

    //dates 
    $short_date   = gmdate('Ymd'); //short date 
    $iso_date   = gmdate("Ymd\THis\Z"); //iso format date 
    $expiration_date = gmdate('Y-m-d\TG:i:s\Z', strtotime('+1 hours')); //policy expiration 1 hour from now 

    $filename=uniqid().".jpg"; // file name to be which file is saved. 
    //POST Policy required in order to control what is allowed in the request 
    //For more info http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html 
    $policy = utf8_encode(json_encode(array(
         'expiration' => $expiration_date, 
         'conditions' => array(
          array('acl' => 'public-read'), 
          array('bucket' => $my_bucket), 
          array('success_action_redirect' => $success_redirect), 
          array('starts-with', '$key','user/'), 
          array('content-length-range', '1', $allowd_file_size), 
          array('x-amz-credential' => $access_key.'/'.$short_date.'/'.$region.'/s3/aws4_request'), 
          array('x-amz-algorithm' => 'AWS4-HMAC-SHA256'), 
          array('X-amz-date' => $iso_date) 
          )))); 

    //Signature calculation (AWS Signature Version 4) 
    //For more info http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html 
    $kDate = hash_hmac('sha256', $short_date, 'AWS4' . $secret_key, true); 
    $kRegion = hash_hmac('sha256', $region, $kDate, true); 
    $kService = hash_hmac('sha256', "s3", $kRegion, true); 
    $kSigning = hash_hmac('sha256', "aws4_request", $kService, true); 
    $signature = hash_hmac('sha256', base64_encode($policy), $kSigning); 

    $arr=array(); 
    $arr["u"]="http://$my_bucket.s3.amazonaws.com/"; 
    $arr["k"]=$filename; 
    $arr["a"]="public-read"; 
    $arr["ac"]="$access_key/$short_date/$region/s3/aws4_request"; 
    $arr["aa"]="AWS4-HMAC-SHA256"; 
    $arr["ad"]=$iso_date; 
    $arr["p"]=base64_encode($policy); 
    $arr["as"]="$signature"; 
    $arr["sar"]="$success_redirect"; 
    $arr["us"]="user/"; 
    echo json_encode($arr); 
    ?>