I could not create Presigned Url using AWS SDK for PHP. My code is -
function connect()
{
// Instantiate the S3 class and point it at the desired host
date_default_timezone_set('GMT');
return S3Client::factory(array(
'region' => 'us-west-2',
'version' => 'latest',
'credentials' => [
'key' => $key,
'secret' => $secret
]
));
function getSignedS3URLForObject($fileName)
{
// GET CURRENT DATE
$milliseconds = round(microtime(true) * 1000);
$expiration = $milliseconds + (1000 * 60 * 60 * 24 * 30 * 2);
$s3 = self::connect();
$command = $s3->getCommand('GetObject', array(
'Bucket' => self::$customerBucket,
'Key' => $fileName,
'ContentType' => 'image/jpeg',
'Body' => '',
'ContentMD5' => false
));
$signedUrl = $command->createPresignedUrl($expiration);
echo urldecode($signedUrl);
return $signedUrl;
}
It gives me next error-
Fatal error: Call to undefined method
Aws\Command::createPresignedUrl() in
/Users/waverley_lv/WaverleySoftware/workspace/fox.php.auto/sites/default/behat-tests/util/S3Utility.php
on line 103
To force download any file on browser, you can use :
$command = $s3->getCommand('GetObject', array(
'Bucket' => 'bucketname',
'Key' => 'filename',
'ResponseContentType' => 'application/octet-stream',
'ResponseContentDisposition' => 'attachment'
));
// Create a signed URL from the command object that will last for
// 2 minutes from the current time
$response = $s3->createPresignedRequest($command, '+2 minutes');
$presignedUrl = (string)$response->getUri();
Using s3.0.0 v3 - I did the following to get this to work.
$command = $s3->getCommand('GetObject', array(
'Bucket' => $this->customerBucket,
'Key' => $fileName,
'ContentType' => 'image/png',
'ResponseContentDisposition' => 'attachment; filename="'.$fileName.'"'
));
$signedUrl = $s3->createPresignedRequest($command, "+1 week");
Related
This PHP function generates a S3 pre-signed URL:
public function generatePreSignedUrl(): string
{
$secretAccessKey = urlencode(env('AWS_SECRET_ACCESS_KEY'));
$bucket = env('AWS_BUCKET');
$client = new S3Client([
'version' => 'latest',
'region' => env('AWS_DEFAULT_REGION'),
'credentials' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => $secretAccessKey,
],
]);
$expires = Carbon::now()->addMinutes(15)->timestamp;
$keyname = 'video.mp4';
$command = $client->getCommand('PutObject', [
'Bucket' => $bucket,
'Key' => $keyname,
'ContentType' => 'video/mp4',
]);
$request = $client->createPresignedRequest($command, $expires);
return (string) $request->getUri();
}
But, when I try to use the generated URL, I get the following error:
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided.
Check your key and signing method.</Message
I am uploading files from php to aws s3. I have successfully uploaded the file.
The url it is returning is => https://BUCKETNAME.s3.ap-south-1.amazonaws.com/images1740/1550830121572.jpg
The actual url is => https://s3.ap-south-1.amazonaws.com/BUCKETNAME/images1740/1550830121572.jpg
(bucket name is coming in starting instead at the end of url)
Because of this it is giving me error while loading images => "Specified Key not found"
$source = $source;
$bucket = 'xxxxxxxxxxxxxxxxx';
$keyname = 'images'.$usr_id."/".$name;
// for push
$s3 = S3Client::factory(
array(
'credentials' => array(
'key' => "xxxxxxxxxxxxxx",
'secret' => "xxxxxxxxxxxxxxx"
),
'version' => 'latest',
'region' => 'ap-south-1'
)
);
try {
// Upload data.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $source,
'ServerSideEncryption' => 'AES256',
));
// Print the URL to the object.
print_r($result);
return $result['ObjectURL'] . PHP_EOL;
// print_r($result);
} catch (S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
Set use_path_style_endpoint to true when initializing the S3 client to have it use the S3 path style endpoint by default when building the object URL. 1
Implementation details has the object URL to be in the path style if the bucket name makes a valid domain name otherwise it fallback to the S3 path style.
You want to keep the later behavior all the time.
$s3 = S3Client::factory(
array(
'credentials' => array(
'key' => "xxxxxxxxxxxxxx",
'secret' => "xxxxxxxxxxxxxxx"
),
'use_path_style_endpoint' => true,
'version' => 'latest',
'region' => 'ap-south-1'
)
);
You can also do as below if you wanted to disable it one-time for the PutObject operation.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $source,
'ServerSideEncryption' => 'AES256',
'#use_path_style_endpoint' => true
));
My error message:
Uncaught Aws\S3\Exception\InvalidRequestException:
AWS Error Code: InvalidRequest,
Status Code: 400, AWS Request ID: xxx,
AWS Error Type: client,
AWS Error Message: The authorization mechanism you have provided is not supported.
Please use AWS4-HMAC-SHA256., User-Agent: aws-sdk-php2/2.7.27 Guzzle/3.9.3 curl/7.47.0 PHP/7.0.15-0ubuntu0.16.04.4
My Code:
<?php
use Aws\S3\S3Client;
require 'vendor/autoload.php';
$config = array(
'key' => 'xxx',
'secret' => 'xxx',
'bucket' => 'myBucket'
);
$filepath = '/var/www/html/aws3/test.txt';
//s3
// Instantiate the client.
$s3 = S3Client::factory();
// Upload a file.
$result = $s3->putObject(array(
'Bucket' => $config['bucket'],
'Key' => $config['key'],
'SourceFile' => $filepath,
'Endpoint' => 's3-eu-central-1.amazonaws.com',
'Signature'=> 'v4',
'Region' => 'eu-central-1',
//'ContentType' => 'text/plain',
//'ACL' => 'public-read',
//'StorageClass' => 'REDUCED_REDUNDANCY',
//'Metadata' => array(
// 'param1' => 'value 1',
// 'param2' => 'value 2'
)
);
echo $result['ObjectURL'];
Cant figure out why I cant get through. I have the right parameters in my call. My code is mostly copied from their aws-sdk-php example page. So it shouldnt be to much fault there.
I am using aws cli and have set upp my configure and credentials file under ~/.aws/
EDIT:
Got it to work! This is my code now:
<?php
// Get dependencies
use Aws\S3\S3Client;
require 'vendor/autoload.php';
// File to upload
$filepath = '/var/www/html/aws3/test.txt';
// instantiate the Client
$s3Client = S3Client::factory(array(
'credentials' => array(
'key' => 'AKIAJVKBYTTADILGRTVQ',
'secret' => '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'
),
'region' => 'eu-central-1',
'version' => 'latest',
'signature_version' => 'v4'
));
// Upload a file.
$result = $s3Client->putObject(array(
'Bucket' => "myBucket",//some filebucket name
'Key' => "some_file_name.txt",//name of the object with which it is created on s3
'SourceFile' => $filepath,
)
);
// Echo results
if ($result){
echo $result['ObjectURL'];
} else{
echo "fail";
}
Try this, it will surely work, the problem in your code is you haven't supplied credentials to factory function.
<?php
ini_set('display_errors', 1);
use Aws\S3\S3Client;
require 'vendor/autoload.php';
//here we are creating client object
$s3Client = S3Client::factory(array(
'credentials' => array(
'key' => 'YOUR_AWS_ACCESS_KEY_ID',
'secret' => 'YOUR_AWS_SECRET_ACCESS_KEY',
)
));
// Upload a file.
$filepath = '/var/www/html/aws3/test.txt';
$result = $s3Client->putObject(array(
'Bucket' => "myBucket",//some filebucket name
'Key' => "some_file_name.txt",//name of the object with which it is created on s3
'SourceFile' => $filepath,
'Endpoint' => 's3-eu-central-1.amazonaws.com',
'Signature' => 'v4',
'Region' => 'eu-central-1',
)
);
echo $result['ObjectURL'];
I am trying to upload a 2GB File to Amazon S3 with Guzzle. I am streaming the content and my code look like this:
$credentials = new Credentials( 'access_id', 'access_key');
$s3 = S3Client::factory(array(
'credentials' => $credentials
));;
try {
$s3->putObject(array(
'Bucket' => $bucket,
'Key' => $obect,
'Body' => (strlen($body) < 1000 && file_exists($body)) ? Guzzle\Http\EntityBody::factory(fopen($body, 'r+')) : $body,
'ACL' => $acl,
'ContentType' => $content_type
));
return true;
} catch (Aws\Exception\S3Exception $e) {
error_log($e -> getMessage() . ' ' . $e -> getTraceAsString());
return false;
}
Now the error I am getting is this:
Fatal error: Uncaught exception
'Guzzle\Http\Exception\CurlException' with message '[curl] 28:
Operation timed out after 30000 milliseconds with 0 out of -1 bytes
received [url]
https://xxxxx.s3.amazonaws.com/6e12e321-adac-42a0-a932-8f345f9dd9c6'
in
How can I modify the timeout for curl with Guzzle?
You may set curl options by this way:
$s3->putObject(array(
'Bucket' => '...',
'Key' => '...',
'Body' => '...',
'ACL' => '...',
'ContentType' => '...',
'curl.options' => array(
CURLOPT_TIMEOUT => 10,
CURLOPT_CONNECTTIMEOUT => 15
)
));
Or try this:
$s3->getConfig()->set('curl.options', array(
CURLOPT_TIMEOUT => 10,
CURLOPT_CONNECTTIMEOUT => 15
)
);
i need expiring downloadlinks for a bucket in eu-central-1.
With $s3->getObjectUrl($bucket, $filename, '+5 minutes'); from the SDK-PHP i only getting unsinged URLs like http://.../file.txt without the querystring.
Complete Code:
require 'vendor/autoload.php';
use Aws\S3\S3Client;
$client = S3Client::factory([
'version' => 'latest',
'region' => 'eu-central-1',
'signature' => 'v4',
'credentials' => [
'key' => 'xxxxx',
'secret' => 'xxxxx'
]
]);
$plainUrl = $client->getObjectUrl('mybucket', 'data.txt');
// > https://my-bucket.s3.amazonaws.com/data.txt
$signedUrl = $client->getObjectUrl('mybucket', 'data.txt', '+10 minutes');
// > https://my-bucket.s3.amazonaws.com/data.txt
I don't know why?
Ahhhh,
getObjectUrl no longer has a third parameter.
This Works:
$cmd = $client->getCommand('GetObject', [
'Bucket' => $bucket,
'Key' => 'test1G.dat'
]);
$request = $client->createPresignedRequest($cmd, '+20 minutes');
$presignedUrl = (string) $request->getUri();