【问题标题】:How to store private pictures and videos in Ruby on Rails如何在 Ruby on Rails 中存储私人图片和视频
【发布时间】:2011-02-14 16:49:03
【问题描述】:

这是一个故事:

  • 用户 A 应该能够上传图片。
  • 用户 A 应该能够设置隐私。 (“公共”或“私人”)。
  • 用户 B 应该无法访问用户 A 的“私人”图片。

我打算让用户 Paperclip 处理上传。

如果我将图像存储在“RAILS_ROOT/public/images”下,任何能猜出文件名的人都可以访问这些文件。 (例如,访问http://example.com/public/images/uploads/john/family.png

我需要使用img 标签显示图像,所以我不能放置除public 之外的文件。

如何确保其他人无法访问用户或组的图像?

(如果我不能用回形针实现这一点,有什么好的解决方案?)

【问题讨论】:

    标签: ruby-on-rails image file-upload privacy


    【解决方案1】:

    你可以让你的 Rails 服务器输出图像文件的内容。这是通过控制器操作完成的(例如,大多数操作打印 HTML,但这个操作会打印 JPG)。

    然后您可以使用您的授权系统来限制控制器级别的访问

    class ImagesController
      #Default show Image method streams the file contents.
      #File doesn't have to be in public/ dir
      def show
        send_file @image.filename, :type => @image.content_type,
                  :disposition => 'inline'
      end
    
      # Use your favorite authorization system to restrict access
      filter_access_to :show, :require => :view, :attribute_check => :true
    end
    

    在 HTML 代码中你可以使用:

    <img src="/images/show/5" />
    

    【讨论】:

    • 谢谢。这很有趣。我会调查一下。
    • 在这种情况下,让网络服务器为send_file 发送的文件提供服务是合理的。看看 Nginx 中的 X-Accel-Redirect 或 Apache 中的 X-Sendfile。有用的链接:1234
    【解决方案2】:

    我会让 Paperclip 在后端使用 S3,将上传的文件设置为私有,然后使用“Query String Request Authentication Alternative”为我的图像标签生成 URL。

    http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html

    【讨论】:

    • 是的,效果很好。 Callmeed 与我同时发布了相同的内容,但他也显示了一些代码。仔细看看他发布的内容并认真考虑。
    【解决方案3】:

    这是我在类似应用程序中的做法。

    • 将您的图像存储在 Amazon S3 而不是本地文件系统上。回形针支持这一点。
    • 在回形针选项中将 :s3_permissions 设置为“私有”
    • 在您的图像模型中,定义一个方法,让您为图像输出一个授权的、有时间限制的 url。

    我的看起来像这样:

    def s3_url(style = :original, time_limit = 30.minutes)
      self.attachment.s3.interface.get_link(attachment.s3_bucket.to_s, attachment.path(style), time_limit)
    end
    
    • 然后,您可以向人们展示图像,前提是他们有权查看它们(实施您喜欢的任何方式),而不必担心人们猜测/查看私人图像。它还可以防止它们在 URL 过期后传递它们(URL 中有一个令牌)。
    • 请注意,您的应用需要花费一些时间来为每张图片生成授权网址。因此,如果您的页面上有多个图像,则会影响加载时间。

    【讨论】:

    • 您对针对图像读取繁重的应用程序优化这种方法有什么建议吗?看来我会有很多额外的应用点击...
    【解决方案4】:

    如果您想自己托管文件,您可以按照建议在控制器级别执行身份验证。例如,我的一个应用程序有一个 AssetController,用于处理“私人”目录中的文件服务。

    我想补充的一件事是,您应该查看this guide 以设置 X-Sendfile,这将使您的应用程序告诉 Web 服务器处理实际发送文件。使用这种方法,您会看到更好的性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-19
      • 2010-12-23
      相关资源
      最近更新 更多