aws s3 php sdk 2 SignatureDoesNotMatch Error - php

I have a bucket created in ap-southeast-1 region with ACL set to private-read. I am able to successfully upload files to folders inside the bucket using the AWS PHP SDK 2 S3Client class. However, I also need to display a link to these files in my application. Hence, when a user clicks a button, I send an AJAX request to my server file, and I get the signedURL which is returned back to the user via json string. However, the url always returns with an XML with error SignatureDoesNotMatch.
Code for getting the signedURL below:
//create the AWS reference string
$client = S3Client::factory(
array(
'key' => T_AWS_KEY,
'secret' => T_AWS_SECRET,
'region' => T_BASE_REGION
)
);
//method 1 - using Command Object
$command = $client->getCommand('GetObject', array(
'Bucket' => T_BASE_BUCKET . "/" . $firmId . "/invoices" ,
'Key' => $arr['file_reference_url'] ,
'ResponseContentDisposition' => 'attachment;filename=' . arr['file_reference_url']
));
$signedUrl = $command->createPresignedUrl('+10 minutes');
echo $signedUrl . "\n\n";
//method 2 - using getObjectUrl
echo $client->getObjectUrl(T_BASE_BUCKET . "/" . $firmId . "/invoices", $arr['file_reference_url'], "+10 minutes");
Any help is appreciated.

It seems you may be confused about what buckets are. Buckets are not nested. It's likely that the value of T_BASE_BUCKET is your bucket and the other parts are part of the object key. Give this a shot:
$objectKey = $firmId . '/invoices/' . $arr['file_reference_url'];
echo $client->getObjectUrl(T_BASE_BUCKET, $objectKey, '+10 minutes');

Related

PHP S3 download: echo huge text variable to browser with header to download

PHP S3 download: echo huge text variable to browser with header to download, but the page is getting timeout and not responding.
Here is my code to download a huge CSV file data from S3 services:
$result = $s3->getObject($_REQUEST['bucket'], $_REQUEST['path'], false);
if($result){
header('Content-type: ' . $result->headers['type']);
header('Content-Length: ' . $result->headers['size']);
header('Content-Disposition: inline; filename="'.$_REQUEST['filename'].'"');
echo $result->body;
} else {
echo 'File not found';
}
I have also increased page execution time:
ini_set('memory_limit', '1024M' );
ini_set('max_execution_time', 0);
I have found an alternate solution to above problem, instead of getting contents from aws and then buffering large amount of data to browser, i created "Public" url from the file and redirect user to the link.
// Getting the URL to an object
$url = $s3->getObjectUrl($targetBucket, $keyname);
// redirect user to the download link
header('Location: '.$url); exit;
If "Private" bucket and files, we can create a temporary bucket and copy the file to that bucket on request, like something below, and then again create link like above.
// temporary bucket for public files
$sourcebucket = '........';
$targetBucket = '........';
$keyname = '........';
// Copy an object.
$s3->copyObject([
'Bucket' => $targetBucket,
'Key' => "{$keyname}",
'CopySource' => "{$sourcebucket}/{$keyname}",
]);
$s3->putObjectAcl(array(
'Bucket' => $targetBucket,
'Key' => $keyname,
'ACL' => 'public-read'
));
I posted here, may be it will help other's. As i was tired for solution! :)
I think the other way of doing what you've got as your own response, is to create a pre-signed request as described in the AWS documentation.
This then means that you can do something like this without having to bother with copying the object to another bucket (and also means you don't have to worry about cleaning up the unsecured bucket/object afterwards) -
$s3Client = new S3Client([
'region' => 'us-east-1',
'version' => 'latest'
]);
$cmd = $s3Client->getCommand('GetObject', [
'Bucket' => $mybucket,
'Key' => $key,
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
// Get the actual presigned-url
$presignedUrl = (string)$request->getUri();
header("Location: " . $presignedUrl);
exit;

Get URL from Firebase Storage (PHP)

I have URL gs://bucket-name.appspot.com/photos/1F0CB8D1-511E-47F2-AA31-8EC131E38672.jpg,
but I need URL http://.... for show photo on site.
How I can get it? Please, explain in PHP.
What you're looking for is called a signed URL in Google Cloud Storage, and you can generate a signed URL in PHP with:
$storage = new StorageClient();
$bucket = $storage->bucket($bucketName);
$object = $bucket->object($objectName);
$url = $object->signedUrl(
# This URL is valid for 15 minutes
new \DateTime('15 min'),
[
'version' => 'v4',
]
);
print('Generated GET signed URL:' . PHP_EOL);
print($url . PHP_EOL);
print('You can use this URL with any user agent, for example:' . PHP_EOL);
print('curl ' . $url . PHP_EOL);

How to check if 2 images with different file names are identical with PHP

I am getting images from the WEB and sending them to an S3 bucket on AWS. Each image gets a random name. But I don't want to store identical twins. So, before storing the image on my server (to then sending it to S3), I need to check if an identical image already exists there (on S3).
I cannot do the check on my server, because files will be deleted after successfully sent to S3.
Here is my code:
$filenameIn = $url_img;
$nome = randomString();
$nome_img = "$nome.png";
$filenameOut = __DIR__ . '/img/' . $nome_img;
$contentOrFalseOnFailure = file_get_contents($filenameIn);
$bucket = 'bucket-img';
if( !$contentOrFalseOnFailure ) {
return "error1: ...";
}
$byteCountOrFalseOnFailure = file_put_contents($filenameOut, $contentOrFalseOnFailure);
if( !$byteCountOrFalseOnFailure ) {
return "error2: ...";
}
// Instantiate the S3 client with your AWS credentials
$aws = new Aws\S3\S3Client([
'version' => 'latest',
'region' => 'sa-east-1',
'credentials' => array(
'key' => 'omissis',
'secret' => 'omissis',
)
]);
/*
I BELIEVE AT THIS POINT I SHOULD MAKE A COMPARISON TO CHECK IF THE FILE THAT
IS ABOUT TO BE SENT TO S3 HAS AN IDENTICAL TWIN THERE, REGARDLESS OF THEIR
RANDOM NAME. IF SO, UPLOAD SHOULD BE ABORTED AND THE SCRIPT SHOULD PROVIDE
ME WITH THE URL OF THE TWIN.
*/
try{
// Send a PutObject request and get the result object.
$result = $aws->putObject([
'Bucket' => $bucket,
'Key' => $nome_img,
'SourceFile' => $filenameOut,
'ACL' => 'public-read'
]);
$r = $aws->getObjectUrl($bucket, $nome_img);
return $r;
} catch (S3Exception $e) {
return $e->getMessage() . "\n";
}
As I said in the code, I should get the url of the twin file, if it exists.
Is that possible?

Drive API Not Syncing PHP

I am using the Google Drive API in my web application. I completely removed the "Getting Started" file and added a couple folders about 5 days ago to the service accounts Google Drive that I am connecting to. But instead of the API returning current data (two folders), it returns old data (the "Getting Started.pdf" file).
Why is the API doing this? How can I use PHP to fix it? I prefer using the SDK functions over the URLs, just so you know.
The code that isn't working is
$pageToken = null;
do {
$response2 = $service->files->listFiles(array(
//'q' => "mimeType='application/vnd.google-apps.folder'",
'spaces' => 'drive',
'pageToken' => $pageToken,
'fields' => 'nextPageToken, files(id, name)',
));
foreach ($response2->files as $file2) {
echo "Found file: " . $file2->name . " " . $file2->id;
}
} while ($pageToken != null);

PHP Script not proceeding ahead with Amazon S3 Upload

I am trying to upload a file to the Amazon S3 using the AWS PHP SDK but whenever I try uploading, the script gives output till the PutObject operation but no output after that operation. I am not even able to dump the result object. The credentials are stored in the .aws in the root folder of my test machine (running Ubuntu). Below is the code -
$s3 = new Aws\S3\S3Client([
'version' => 'latest',
'region' => 'us-east-1'
]);
echo "<br />".realpath(UPLOAD_DIR . $apiKEY . "/" . $name);
try {
$result = $s3->putObject([
'Bucket' => 'quicklyusercannedspeechbucket',
'ContentType' => 'text/plain',
'Key' => $apiKEY . "/" . $name,
'SourceFile' => realpath(UPLOAD_DIR . $apiKEY . "/" . $name)
]);
var_dump($result);
}
catch(\Aws\S3\Exception\S3Exception $e) {
echo $e->getAwsErrorCode();
}
echo "Finished";
var_dump($result);
When I run the above code, I don't get any output for the $result array. Any idea what might be happening?
Any help is appreciated ^_^
-Pranav
Use below code to view if your image is uploaded successfully
try {
$result = $s3->putObject([
'Bucket' => 'quicklyusercannedspeechbucket',
'ContentType' => 'text/plain',
'Key' => $apiKEY . "/" . $name,
'SourceFile' => realpath(UPLOAD_DIR . $apiKEY . "/" . $name)
]);
$s3file='http://quicklyusercannedspeechbucket.s3.amazonaws.com/'.$name;
echo "<img src='$s3file'/>";
echo 'S3 File URL:'.$s3file;
var_dump($result);
}
catch(\Aws\S3\Exception\S3Exception $e) {
echo $e->getAwsErrorCode();
}
You can get step by step detail from here Amazon S3 File Upload Using PHP
It seems that I had put the credentials in the wrong folder. As per the NGINX, the default folder for storing the credentials was /var/www rather than the home directory of the user.
Also, I turned on the display_errors in the php.ini which helped me find that the AWS SDK was having problems with the credentials.
Thanks!

Categories