【问题标题】:Prevent bots from accessing rails active_storage images防止机器人访问 rails active_storage 图像
【发布时间】:2020-11-20 01:54:53
【问题描述】:

我的网站有大量图表,这些图表每天都会在新数据可用时重新计算。这些图使用active_storage 存储在Amazon S3 上。一个典型的例子是

# app/models/graph.rb
class Graph < ApplicationRecord
  has_one_attached :plot
end

在视图中

<%= image_tag graphs.latest.plot %>

graphs.latest 检索最新图的位置。每天都会创建一个新图表和附加图表,并删除旧图表/图表。

许多机器人,包括来自 Google 和 Yandex 的机器人正在为图表编制索引,但是当机器人返回并再次通过以下网址访问图像时会生成异常

www.myapp.com/rails/active_storage/representations/somelonghash

有没有办法为图表生成一个持久链接,当图表/图表被删除然后重新计算时不会过期。如果做不到这一点,有没有办法阻止机器人访问这些地块。

请注意,我目前在 routes.rb 文件的末尾有一个总称:

get '*all', to: 'application#route_not_found', constraints: lambda { |req|
      req.path.exclude? 'rails/active_storage'
    } if Rails.env.production?

在总括中排除活动存储是对此issue 的回应。删除 active_storage 豁免是很诱人的,但这可能会停止正确的 active_storage 路由。

也许我可以在rack_rewrite.rb 中添加一些东西来解决这个问题?

【问题讨论】:

    标签: ruby-on-rails amazon-s3 robots.txt rails-activestorage


    【解决方案1】:

    有趣的问题。

    一个简单的解决方案是使用send_data 功能直接发送图像。但是,这可能有它自己的问题,主要是在可能增加服务器带宽使用(并降低服务器性能)方面。但是,如果您不想在创建重定向模型及其相关逻辑方面遇到以下麻烦,那么您需要这样的解决方案。


    原答案

    重定向需要设置某种Redirects::Graph 模型。这基本上可以验证一个图表是否被删除并重定向到新图表而不是请求的图表。它将有两个字段,一个old_signed_id (biglonghash) 和一个new_signed_id

    每次删除

    我们需要填充重定向模型,并在每次创建新图表时添加一个新条目(我们应该能够以某种方式从 blob 生成 signed_id)。

    为了提高性能,并避免连续出现大量重定向,这可能会导致不同的错误/问题。您必须管理请求更改。 IE:假设你现在有一个重定向A =&gt; B,你删除BC 替换它现在你需要一个A =&gt; CB =&gt; C(以避免A =&gt; B =&gt; C 重定向),这个链可能会变得很长确实。这可以通过添加新的signed_id =&gt; new_id 索引并执行Redirects::Graph.where(new_signed_id: old_signed_id).update_all(new_signed_id: new_signed_id) 来更新所有相关的旧重定向来有效地处理,只要您重新生成图表。

    控制器本身更棘手,我能想到的最干净的方法是猴子修补ActiveStorage::RepresentationsController 以添加一个before_action 执行类似的操作(可能无法按原样工作,params[:signed_id] 和表示路径可能不正确):

    before_action :redirect_if_needed
    
    def redirect_if_needed
      redirect_model = Redirects::Graph.find_by(old_signed_id: params[:signed_id])
      redirect_to rails_activestorage_representations_path(
        signed_id: redirect_model.new_signed_id
      ) if redirect_model.present?
    end
    

    如果您为您的数据库设置了版本控制(IE:Papertrail gem 或其他东西),您可能能够通过一些工作来计算出old_signed_idnew_signed_id,并为当前导致错误的 url 构建重定向.否则,遗憾的是,这种方法只能防止将来出现错误,并且可能无法使当前损坏的 url 正常工作。

    理想情况下,尽管您会更新 blob 本身以使用新图而不是旧图而不是删除,但不确定这是否可行/实用。

    【讨论】:

    • 谢谢你。虽然它比我希望的要复杂得多,但这似乎有潜力,但我不知道如何“以某种方式从 blob 生成signed_id”。另外,重定向条目不需要存储在数据库中吗?
    • api.rubyonrails.org/v6.1.3.1/classes/ActiveStorage/Blob.html 看起来它只是 blob 上的 signed_id,所以实际上不要生成它。至于重定向,是的,您必须将它们存储在数据库中,避免这种情况的唯一方法是a)首先不删除它们,而是更新blob以避免signed_id无效,或者b ) 防止机器人抓取 ID。如果您可以使用自己的 URL 来提供图像而不是活动记录,这可能是可能的。我相信您可以使用send_data 发送图像而不是使用资产管道。
    • 如果我使用send_data,网址会保持不变吗?如果是这样,这听起来是一个很好的解决方案。假设图像是graph.latest.plot,语法是什么?是否有任何缺点,例如它是从活动存储而不是通过服务器流式传输的吗?
    • URL 应该与/download/graphs/vpq34or8vawo 一样,最后一位是图形的 ID(友好的 id gem 在这里很有帮助,或类似的东西)。它会通过我想象的服务器流式传输,因此这可能是服务器带宽使用问题。至于如何使用,请在线搜索“rails send_data images”以获取使用示例。在这种情况下,您只需要确保您有一个跟踪图表的总体模型,因此它知道要发送的正确图像。
    • 关于通过服务器的流媒体,你认为active_storage js库会支持direct_upload: true直接上传吗?在我看来send_data 方法提供了一个可行的解决方案,所以我认为您已经获得了奖金,谢谢。但是,我不愿接受当前的答案,因为它需要阅读大量文本。我认为其他人会感到困惑。您如何编辑它,或者就send_data 方法提供第二个简洁的答案。
    【解决方案2】:

    你试过了吗?

    file /robots.txt put

    User-agent: *
    Disallow: /rails/active_storage*
    

    【讨论】:

    • 是的,它不适用于 PetalBot,可能还有其他机器人。
    • @Obromios try like this 你可以指定 -> User-agent: PetalBot Disallow: /
    • 我确实尝试过,但 PetalBot 似乎忽略了 robots.txt
    猜你喜欢
    • 2016-04-25
    • 2017-01-07
    • 1970-01-01
    • 2011-04-28
    • 2011-10-16
    • 2012-11-19
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    相关资源
    最近更新 更多