如何在Ruby on Rails中存储私人图片和视频

时间:2010-05-02 04:55:31

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

这是一个故事:

  • 用户A应该可以上传图片。
  • 用户A应该能够设置隐私。 (“公开”或“私人”)。
  • 用户B不应该能够访问用户A的“私人”图像。

我打算用Paperclip来处理上传。

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

我需要使用img标记显示图片,因此我无法放置public以外的文件。

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

(如果我用Paperclip无法做到这一点,那么什么是好的解决方案?)

4 个答案:

答案 0 :(得分:8)

您可以让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" />

答案 1 :(得分:4)

我会让Paperclip在后端使用S3,将上传的文件设置为私有,然后使用“查询字符串请求身份验证替代”来生成我的图像标记的URL。

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

答案 2 :(得分:4)

以下是我在类似应用程序中执行此操作的方法。

  • 将图像存储在Amazon S3而不是本地文件系统上。 Paperclip支持这一点。
  • 在您的回形针选项中将您的:s3_permissions设置为“private”
  • 在您的图片模型中,定义一种方法,让您输出图像的授权时间限制网址。
我的样子如下:

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中有一个令牌)。
  • 请注意,您的应用需要一段时间才能为每张图片生成授权网址。因此,如果页面上有多个图像,则会影响加载时间。

答案 3 :(得分:1)

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

我想补充的一点是,您应该查看this guide来设置X-Sendfile,这将让您的应用程序告诉Web服务器处理实际发送文件。通过这种方法,您会看到更好的表现。