Reputation: 33
I'm trying to host images on s3 with cloudfront but I want the client to choose the size of the image when making the image request using query parameters.
I want to used signed url's so if a user has a signed url they can access that image in any size they want. The problem is, the image size query params have to be appended to the url during signing otherwise the appending of the size query params will result in the signature check not passing. Meaning if I want the image in two different sizes, I need to make two round trips to the my server to sign the url with the size parameters, then fetch the images from cloudfront. I want to avoid this.
Is there any way I could accomplish this?
Upvotes: 2
Views: 1886
Reputation: 316
You can also add the asterisk at the end of the path (like this https://example.com/images/funny/cat.png*
) to allow further optional parameters to be added.
Upvotes: 1
Reputation: 33
Sovled! Thanks to @Michael - sqlbot. By using a custom policy I can return any image dimensions I want including the original size using one signed url. In case anyone else has this issue here's how I did it:
My php code to generate the signed url:
public static function signedImageUrl($resource)
{
// Build Url
$url = self::CLOUDFRONT_BASE . ltrim($resource, '/') . '?w=*&h=*';
// Create a CloudFront Client
$client = new CloudFrontClient([
'version' => '2014-11-06',
'region' => 'us-east-2'
]);
// Set up parameter values for the resource
$expires = time() + 300;
// Policy
$policy = '{
"Statement": [
{
"Resource":"' . $url . '",
"Condition":{
"DateLessThan":{"AWS:EpochTime":' . $expires . '}
}
}
]
}';
// Create a signed URL for the resource using the canned policy
$signedUrlCannedPolicy = $client->getSignedUrl([
'url' => $url,
'policy' => $policy,
'private_key' => env('AWS_CLOUDFRONT_PRIVATE_KEY_PATH'),
'key_pair_id' => env('AWS_CLOUDFRONT_KEY_PAIR_ID')
]);
return $signedUrlCannedPolicy;
}
Where CLOUDFRONT_BASE is the .cloudfront.net/ domain for my cloudfront distribution, and $resource is the filename (e.g. my_profile_image.png)
At this point I get my signed image and can then modify the w and h query parameters on the client to my hearts content. My lambda function is fired on the cloudfront ViewerRequest event and will direct cloudfront to load either the image with specified dimensions, or to load the original image if w and h are both *.
Upvotes: 1