Cloudfront presigned expires time not updating

I’m setting up Cloudfront CDN to serve private content.

My upload works and Shrine is correctly generating a cloudfront signed url with the below code. Only problem is that the expires: parameter which is required for Cloudfront signed urls appears to only get set on initialization and not updated per request.

In the example I’ve set the expires time to be 30 seconds from Time.now, the url works when starting the server, but refreshing the page doesn’t generate a new url with an updated expires at time.

I tried moving the :url_options plugin into the VideoUploader instead of the initializer to see if that fixed the problem but the results were the same.

Is there a way to make sure Shrine updates the expires: param per request?

video_uploader.rb

class VideoUploader < Shrine
    plugin :url_options, store: {host: "http://[domain].cloudfront.net", expires: Time.now + 30 }
end

initializers/shrine.rb

require "shrine"
require "shrine/storage/s3"
require "aws-sdk-cloudfront"

s3_options = {
   [AWS Config]
}
signer = Aws::CloudFront::UrlSigner.new(
    key_pair_id: "id",
    private_key_path: "private_key.pem"
)

Shrine.storages = {
    cache: Shrine::Storage::S3.new(signer: signer.method(:signed_url), prefix: "cache", **s3_options),
    store: Shrine::Storage::S3.new(signer: signer.method(:signed_url), prefix: "store", **s3_options),
}

Found the answer the url_options docs had an example to call the plugin dynamically. The below code generates a new signed url per request.

plugin :url_options, store: -> (file, options) do
        { host: "https://[domain].cloudfront.net", expires: Time.now + 30 }
end
1 Like