0

I have a file in S3, that with CloudFront using a cname (with amazon SSL Certificate) while the file is public I can access it without problems using the URL.

Valid examples in public files:

https://xxxxxxxxxxxxx.cloudfront.net/media/logos/logo1.png
https://cdn.{mydomain.com}/media/logos/logo1.png
https://s3.amazonaws.com/{mys3bucketname}/media/logos/logo1.png

In laravel

$disk = Storage::disk('cnames3');
$tempUrl = $disk->temporaryUrl($file, now()->addMinutes(5));

The best option I found was: Should I use CloudFront together as TemporaryUrl for sensitive files in s3

'cnames3' => [
        'driver' => 's3',
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'url' => env('AWS_URL'),
        'endpoint' => env('AWS_ENDPOINT'),
]

=====
.env
AWS_BUCKET={mys3bucketname}
AWS_ENDPOINT=https://xxxxxxxxxxxxx.cloudfront.net
AWS_URL=https://cdn.{mydomain.com}

but the URL that I produced includes the name of the bucket, and so it does not work for me, since it denies me access.

https://cdn.{mydomain.com}/{mys3bucketname}/media/logos/logoprivate.png?{params}

how can I get a URL compatible with CNAME, or what can I do so I can use my own domain with signed URLs; I look for this format:

https://cdn.{mydomain.com}/media/logos/logoprivate.png?{params}

if I have the private file and use "temporaryUrl" without endpoint it returns a valid url:

 https://s3.amazonaws.com/{mys3bucketname}/media/logos/logoprivate.png?{params}

but without my domain, which does not work for me, I have been looking for a solution for hours, I hope you can help this beginner in the subject

nasatome
  • 521
  • 6
  • 13

2 Answers2

2

You have to set bucket_endpoint to true in config then it doesn't append bucket name in your domain.

'cnames3' => [
        'driver' => 's3',
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'url' => env('AWS_URL'),
        'bucket_endpoint' => true,  //add this 
        'endpoint' => env('AWS_ENDPOINT'),
]

You can check here https://github.com/aws/aws-sdk-php/blob/master/src/S3/S3Client.php

rkj
  • 8,067
  • 2
  • 27
  • 33
  • now if it is the right format! -> but it does not work <-: I was reading a bit more, and I do not know if it is because the signed format is different when using cloudfront: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/service_cloudfront-signed-url.html – nasatome Aug 15 '18 at 14:46
  • 3 years later, a true savior! – elgranchuchu Mar 27 '21 at 13:59
0

(Assuming that CloudFront with CNAME is already working)

in options of CloudFrontDistributions>{yourCFID} In Origins tab edit:

Origin Access Identity -> Use an Identity

Restrict Bucket Access: yes (and Yes, Update Bucket Policy)

In Default Cache Behavior Settings:

Restrict Viewer Access (Use Signed URLs or Signed Cookies) = YES

Trusted Signers = SELF

1.- First create Private Key from CloudFront

Creating CloudFront Key Pairs for Your Trusted Signers

2.-

composer require league/flysystem-aws-s3-v3

OR

composer require aws/aws-sdk-php

3.- Create functions: Signing CloudFront URLs for Private Distributions

Example:

 use Aws\CloudFront\CloudFrontClient;

...

//$filesystemDisk = "s3"
private function signUrl($filesystemDisk, $resourceKey = null)
{
    $cloudFront = new CloudFrontClient([
        'region'  => config('filesystems.disks.' . $filesystemDisk . '.region'),
        'version' => '2014-11-06',
    ]);
    // Set up parameter values for the resource
    //example
    $resourceKey = 'https://cdn.mydomain.com/media/logos/logoprivate.jpg';
    $expires = time() + 200;

// Create a signed URL for the resource using the canned policy
        $signedUrlCannedPolicy = $cloudFront->getSignedUrl([
            'url'         => $resourceKey,
            'expires'     => $expires,
            'private_key' => '/path/to/keys/amazon/cloudfront/private/pk-APKFYWFAKEFAKEFAKEIQ.pem',
            'key_pair_id' => 'APKFYWFAKEFAKEFAKEIQ',
        ]);

        return $signedUrlCannedPolicy;
    }

4.- Done; you get (with your cname):

https://cdn.{mydomain.com}/media/logos/logoprivate.jpg?{params}
nasatome
  • 521
  • 6
  • 13