授权访问附件(使用回形针 gem)

Authorizing Access to Attachments (using paperclip gem)

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

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

因此,由于附件位于 public 目录中:任何人都可以访问此图片,如果他们知道 url:

#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 将无法停止访问保存在 public 目录中的附件。

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

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

Paperclip Documentation

您有 2 个选择:

第一个选择是将上传的文件存储在non-public目录中,并提供一个控制器动作来验证用户并让她下载文件。您可以使用任何身份验证库。至于下载部分,直接用辅助方法send_file

模特class

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

第二个选择很简单,将文件保存在public目录中,但给它一个随机路径,很难猜到。并且您还必须提供一个控制器操作来验证用户,但是这次,您不是将文件发送给用户,而是将他们重定向到文件 URL.

优缺点

第一个选择非常安全,但它需要您的 rails 应用程序来处理文件下载。如果您使用的是线程化或预分叉的服务器,这可能会影响并发性。

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