20

According to this link http://docs.aws.amazon.com/aws-sdk-php/v2/guide/service-s3.html, I can easily create a presigned link just adding the life span to getObjectUrl

$signedUrl = $client->getObjectUrl($bucket, 'data.txt', '+10 minutes');
// > https://my-bucket.s3.amazonaws.com/data.txt?AWSAccessKeyId=[...]&Expires=[...]&Signature=[...]

But I get a plain url, you know, without the awsaccesskeyid and expires parameters,

Here's my code:

$bucket = 'imagenesfc';
$keyname = 'NASimagenes/codigoBarraBoleto/1001000098.png';
$filepath = 'NASimagenes/codigoBarraBoleto';

// Instantiate the client.
$s3 = S3Client::factory(array(
    'version' => 'latest',
    'region' => 'us-west-1'
));
 $signedUrl = $s3->getObjectUrl($bucket, $keyname,'+10 minutes');
// > https://my-bucket.s3.amazonaws.com/data.txt?AWSAccessKeyId=[...]&Expires=[...]&Signature=[...]
 echo $signedUrl."<br>";

EDIT: I have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables

My echo looks like:

https://s3-us-west-1.amazonaws.com/imagenesfc/NASimagenes/codigoBarraBoleto/1001000098.png

What's wrong?

2
  • Where are you passing the aws key and secret, to be used in the signing process? Commented May 29, 2015 at 11:49
  • They are set as environment variables. Commented May 29, 2015 at 12:55

2 Answers 2

45

Well, if anyone else has any trouble with this like I did, here is the answer, I went into the amazon php development forums and got help from the profesionals.

It seems you may be flip-flopping between Version 2 and Version 3 of the SDK or looking at the wrong document. Make sure you are getting the one you intend to use and are looking at the correct documentation. They are different.

V3 - Composer Requirement: {"aws/aws-sdk-php": "~3.0"} - User Guide: http://docs.aws.amazon.com/aws-sdk-php/v3/guide/index.html - API Docs: http://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html - Pre-signed URL Docs: http://docs.aws.amazon.com/aws-sdk-php/v3/guide/service/s3-presigned-url.html

V2 - Composer Requirement: {"aws/aws-sdk-php": "~2.8"} - User Guide: http://docs.aws.amazon.com/aws-sdk-php/v2/guide/index.html - API Docs: http://docs.aws.amazon.com/aws-sdk-php/v2/api/index.html - Pre-signed URL Docs: http://docs.aws.amazon.com/aws-sdk-php/v2/guide/service-s3.html#creating-a-pre-signed-url

Mini step-by-step guide of what you have to do:

1.Install composer, preferably using sudo:

    sudo curl -sS https://getcomposer.org/installer | sudo php

2.Go to your project folder and create a composer.json file, with the version you want/need, you can find releases here: https://github.com/aws/aws-sdk-php/releases, commands for each version seem to be very version specific, be careful, this was my main problem.

{
    "require": {
        "aws/aws-sdk-php": "~3.0"
    }

}

3.Then go to your project folder in the terminal, and install sdk via composer and update afterward like: (if you change version you have to update again.)

    sudo php composer.phar install
    sudo php composer.phar update

4.Then everything is ready for you to follow proper version documentation, in my case for version "aws/aws-sdk-php": "~3.0" and for presigned url, what worked was:

    require 'vendor/autoload.php';
    use Aws\S3\S3Client;
    use Aws\S3\Exception\S3Exception;

    $sharedConfig = [
        'region'  => 'us-west-1',
        'version' => 'latest'
    ]; //I have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables

    $s3Client = new Aws\S3\S3Client($sharedConfig);

    $cmd = $s3Client->getCommand('GetObject', [
        'Bucket' => $bucket,
        'Key'    => $keyname
    ]);

    $request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
    $presignedUrl = (string) $request->getUri();
    echo $presignedUrl;

I hope this helps anyone facing the same problems as I did.

Sign up to request clarification or add additional context in comments.

5 Comments

Here it is +20 minutes. Is there a limit on minimum time? I am trying +3 seconds, It is taking more than 10 seconds to expire.
Documentation doesn't say anything about limits, "The time at which the URL should expire. This can be a Unix timestamp, a PHP DateTime object, or a string that can be evaluated by strtotime()." docs.aws.amazon.com/aws-sdk-php/v3/api/…
Great! Step 4 gave me the info I was after. You saved me hours tonight.
That's exactly what Storage::disk('s3')->temporaryUrl() does without the need for you to use AWS Sdk explicitly
Anyone reading this: Please Help: I am able to generate presigned URL. But it has X-Amz-Credential parameter which contains AWS Access Key ID as value; Is it Ok? Can we generate pre-signed url without this parameter; Also it displays the entire S3 File URL is it not? If we do not want S3 Url to be displayed, is CloudFront Distribution mandatory? Is there no other way for pre-signed URL?
2

If you're using Laravel you can easily get a temporary URL for S3, as documented here: https://laravel.com/docs/master/filesystem#file-urls

Example of your Image model would be:

class Image extends Model
{

    ...

    public function getTemporaryUrlAttribute()
    {
        return Storage::disk('s3')->temporaryUrl(
            $this->path,
            now()->addSeconds(10)
        );
    }
}

Then in your HTML it would be:

<img width="100px" src="{{$image->temporaryUrl}}">

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.