授权访问附件(使用paperclip gem)

时间:2016-01-10 23:08:39

标签: ruby-on-rails ruby paperclip

默认情况下:回形针gem将附件保存在公共目录中。据我了解:根据定义,公共目录中的文件始终可供用户使用。特别是如果用户知道公共目录中某个附件的URL:该附件不安全。

示例:以下是使用回形针时图像附件的默认保存文件结构:

default_saving_structure

因为附件位于公共目录中:任何人都可以访问此图像,如果他们知道这个网址:

#image accessible to everyone when stored in the public directory
http://localhost:3000/system/users/ex_imgs/000/000/031/original/nthornepng.png?1452466215

我对authorization library: Pundit非常熟悉。但是,Pundit将无法停止访问保存在公共目录中的附件。

问题:我在哪里/如何保存附件,以便我可以授权访问这些附件?如果公共目录不是保存它们的地方:在哪里可以保存附件,以便在访问附件之前验证必须成功?

我熟悉this article,但我仍然在努力解决这个问题。

Paperclip Documentation

1 个答案:

答案 0 :(得分:2)

您有两个选择:

首选是将上传的文件存储在非公共目录中,并提供控制器操作以对用户进行身份验证并让她下载该文件。您可以使用任何身份验证库。至于下载部分,只需使用辅助方法send_file

模型类

class MyModel < ActiveRecord::Base
  has_attached_file :image, :path => '/non-public/dir/:attachment/:id/:style/:basename.:extension',
                            :url => '/downloads/:id'
end

控制器

class DownloadsController
  def show
    # Authenticate user
    model = MyModel.find(params[:id])
    send_file model.image.path
  end
end

第二种选择很简单,将文件保存在公共目录中,但是给它一个难以猜测的随机路径。而且您还必须提供控制器操作来对用户进行身份验证,但这一次,您只需将文件重定向到文件URL,而不是将文件发送给用户。

优点和缺点

第一种选择非常安全,但它需要您的rails应用程序来处理文件下载。如果您正在使用线程或preforked服务器,这可能会降低并发性。

第二种选择不太安全,但您可以依靠HTTP服务器(例如Nginx)来处理文件下载,而rails应用程序只进行身份验证。它的速度要快得多。