Rails adds the ability to pass the expires_at option to ActiveStorage::Blog#signed_id
Rails adds the ability to pass the expires_at
option
to ActiveStorage::Blob#signed_id.
The signed_id
attribute of an ActiveStorage Blob is a unique identifier
for the blob that is signed with a secret key.
It makes it safe to share the signed ID with the client
without worrying about unauthorized access to the blob.
Signed IDs can be used to:
-
Generate URLs for downloading or streaming blobs.
-
Generate pre-signed URLs for blobs that the client can use to upload files directly to the storage service.
-
Identify blobs that the client has uploaded.
Till Rails 7.1
ActiveStorage URLs are permanent by default, but you can use the expires_in option to create expiring URLs. This can be useful for sharing sensitive files or files you don't want publicly accessible forever.
Till Rails 7.1,
to create a signed ID for ActiveStorage blob,
you need to use the signed_id
method as below:
class User < ApplicationRecord
has_one_attached :unique_identification_document
end
user.unique_identification_document.attach(
io: File.open('path/to/file'),
file_name: 'file_name.png',
content_type: 'image/png'
)
# Create a signed expiring URL
signed_id = user.unique_identification_document.signed_id(expires_in: 1.minute)
=> "eyJfcmFpbHMiOnsiZGF0YSI6MSwiZXhwIjoiMjAyMy0xMC0yMFQwOTo0MTo1Ny4yMTZaIiwicHVyIjoiYmxvYl9pZCJ9fQ==--c34f0f13f53411dbd55bbf14184d8d1d122cef4b"
blog = ActiveStorage::Blob.find_signed(signed_id)
=> #<ActiveStorage::Blob:0x000000010db2bb38
id: 1,
key: "io9fm1hjblzq5zsvge2hp5si3oev",
filename: "file_name.png",
content_type: "image/png",
....
# After 1 minute
blog = ActiveStorage::Blob.find_signed(signed_id)
=> nil
After Rails 7.1
The recent changes in Rails allow you to pass the expires_at
option.
When using the expires_in
option to generate an expiring URL,
the URL will change each time it is generated.
This means the browser cannot cache the URL,
and
the user will have to download the file each time they access it.
In contrast,
when using the expires_at
option,
the URL will remain the same until it expires.
This means that the browser can cache the URL,
and
the user will not have to download the file again
if they access it within the cache window.
user.unique_identification_document.signed_id(expires_at: 1.minute)
rails_blob_path(
user.unique_identification_document,
disposition: "attachment",
expires_at: 1.hour.from_now.beginning_of_hour
)
<%= image_tag rails_blob_path(
user.unique_identification_document.variant(resize: "100x100"),
expires_at: 1.hour.from_now.beginning_of_hour
)
%>
To know more about this feature, please refer to this PR.