“将S3与Active Storage一起使用时,“请求已过期”

问题描述 投票:4回答:2

我是第一次使用ActiveStorage。在开发过程中一切正常,但在生产中(Heroku),我的图像无故消失了。

他们第一次显示正常,但现在没有图像显示。在控制台中,我可以看到此错误:

GET https://XXX.s3.amazonaws.com/variants/Q7MZrLyoKKmQFFwMMw9tQhPW/XXX 403 (Forbidden)

如果我尝试直接访问该URL,则会得到XML

<Error>
  <Code>AccessDenied</Code>
  <Message>Request has expired</Message>
  <X-Amz-Expires>300</X-Amz-Expires>
  <Expires>2018-07-24T13:48:25Z</Expires>
  <ServerTime>2018-07-24T15:25:37Z</ServerTime>
  <RequestId>291D41FAC6708334</RequestId>      
  <HostId>lEVGuwA6Hvlm/i40PeXaje9SEBYks9+uk6DvBs=</HostId>
</Error>

这是我的看法

<div class="cover" style="background-image: url('<%= rails_representation_path(experience.thumbnail) %>')"></div>

这是我在模型中所拥有的

def thumbnail
  self.cover.variant(resize: "300x300").processed
end

简单来说,我不希望图像过期但要一直存在。

谢谢

ruby-on-rails amazon-s3 ruby-on-rails-5 rails-activestorage
2个回答
5
投票

ActiveStorage不支持未过期的链接。它使用到期链接(私有),并且仅支持在服务上以私有形式上载文件。

这对我来说也是一个问题,仅对S3做2个([补丁(警告),one simple ~30lines覆盖ActiveStorage以仅与未到期的(公共)链接一起使用,以及another that add an acl option to has_one_attached and has_many_attached methods

希望有帮助。

0
投票
您的问题并没有这么说,但是通常将带有CDN的CDN与Rails应用程序结合使用,例如AWS CloudFront。特别是在Heroku上,您可能想节省计算能力。

这里是在这种情况下发生的事情。您照常渲染页面,并且所有图像都从资产宿主CDN请求,因为这是配置成集成页面的方式。它的设置是从原点获取缓存中找不到的任何内容,这又是您的应用程序。

首先所有图像请求都通过。 ActiveStorage控制器为它们创建签名的URL,CDN继续传递它们,但也对其进行缓存。

现在出现了问题。默认情况下,签名的URL会在5分钟后过期,但是CDN缓存通常会更长。这是因为通常您使用摘要资产,这意味着它们在更改时不是按时间而是按名称失效。

解决方案很简单。增加签名URL的有效期,使其长于缓存的TTL。现在,缓存会在其失效之前删除已缓存的签名URL。

详细信息请使用5.2中的ActiveStorage::Service.url_expires_in或直接在初始化程序Rails.application.config.active_storage.service_urls_expire_insee this answer中设置URL到期。

要在CloudFront中设置缓存TTL:打开AWS控制台,选择分发,打开“行为”选项卡,向下滚动到以下字段:

the cloudfront ttl fields

然后有选择地发出无效信息以强制重新缓存所有内容。

请记住,需要进行安全权衡。如果图像内容是私有的,则它们很可能不属于CDN,并且也不应该具有持久的临时URL。在这种情况下,请选择一个完全免除CDN附件的解决方案。您的应用程序将不得不在呈现相关页面的顶部处理对所有附加资产的URL签名的额外负担。

还要记住,这不一定是一个好的解决方案,而是更多的解决方法。使用上述设置,您将缓存重定向,而较重的请求将直接进入您的存储桶。 CDN的通常情况是大型媒体,而不是轻量级重定向。您确实可以减轻应用程序处理大量请求的负担。应该考虑多少是有效的优化。

© www.soinside.com 2019 - 2024. All rights reserved.