11
votes

I am developing a Web Application using PHP. In my application, I need to upload the file to the AWS S3 bucket using Presigned URL. Now, I can read the private file from the S3 bucket using pre-signed like this.

$s3Client = new S3Client([
            'version' => 'latest',
            'region' => env('AWS_REGION', ''),
            'credentials' => [
                'key' => env('AWS_IAM_KEY', ''),
                'secret' => env('AWS_IAM_SECRET', '')
            ]
        ]);

            //GetObject
        $cmd = $s3Client->getCommand('GetObject', [
                'Bucket' => env('AWS_BUCKET',''),
                'Key'    => 'this-is-uploaded-using-presigned-url.png'
            ]);

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


        //This is for reading the image. It is working.
        $presignedUrl = (string) $request->getUri();

When I access the $presignedUrl from the browser, I can get the file from the s3. It is working. But now, I am uploading a file to S3. Not reading the file from s3. Normally, I can upload the file to the S3 like this.

$client->putObject(array(
    'Bucket' => $bucket,
    'Key'    => 'data.txt',
    'Body'   => 'Hello!'
));

The above code is not using the pre-signed URL. But I need to upload the file using a pre-signed URL. How, can I upload the file using a pre-signed URL. For example, what I am thinking is something like this.

$client->putObject(array(
        'presigned-url' => 'url'
        'Bucket' => $bucket,
        'Key'    => 'data.txt',
        'Body'   => 'Hello!'
    ));

How can I upload?

1

1 Answers

2
votes

It seems reasonable that you can create a pre-signed PutPobject command by running:

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

$request = $s3Client->createPresignedRequest($cmd, '+20 minutes')->withMethod('PUT');

Then you might want to perform the PUT call from PHP using:

file_put_contents($request->getUri(), 'Hello!', stream_context_create([
  'http' => [ 'method' => 'PUT' ] ]);

If you want to create a URL that a browser can submit, then you need to have the browser send the file as a form POST. This AWS documentation explains how to create a pre-signed POST request fields that you then need to put into an HTML form and display to the user: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-presigned-post.html

Also, this answer might be useful: https://stackoverflow.com/a/59644117/53538