繁体   English   中英

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

[英]"Request has expired" when using S3 with Active Storage

我是第一次使用 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>

这就是我在 model 中所拥有的

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

简而言之,我不希望图像过期,而是一直存在。

谢谢

ActiveStorage 不支持非过期链接。 它使用过期链接(私人),并支持仅在您的服务中将文件上传为私人文件。

这对我来说也是一个问题,并且仅针对 S3 做了 2 个补丁(警告), 一个简单的 ~30 行覆盖 ActiveStorage 以仅使用非过期(公共)链接, 另一个向 has_one_attached 和 has_many_attached 方法添加 acl 选项.

希望能帮助到你。

我有同样的问题,但在我更正计算机上的时间后,问题就解决了。 这是一个服务器时间差异,aws 服务器无法识别。

您的问题并没有这么说,但是将 AWS CloudFront 之类的 CDN 与 Rails 应用程序一起使用是很常见的。 特别是在 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_in中的初始值设定项中设置 URL 到期, 请参阅此答案以了解详细信息。

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

Cloudfront ttl 字段

然后可选地发出失效以强制重新缓存所有内容。

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

进一步记住,这不一定是一个好的解决方案,而是更多的解决方法。 通过上述设置,您将缓存重定向,而较重的请求将直接命中您的存储桶。 CDN 的常见场景是大型媒体,而不是轻量级重定向。 不过,您确实减轻了应用程序处理大量请求的负担。 应该研究多少是有效的优化。

#production.rb

改变

config.active_storage.service =:本地

config.active_storage.service =:亚马逊

无论您在 storage.yml 中定义什么,都应该匹配 aws/amazon

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM