保护Rails应用程序中的public / content内容

我正在维护一个Rails应用程序,其中包含公共/文件夹中的内容,现在需要通过登录进行保护。 我们正在考虑将这些文件夹移动到public / public之外的路径中,并编写Rails控制器来提供内容。

在我们开始写这篇文章之前,我很好奇是否还有其他人遇到过这类问题? 我找了一些可能已经这样做但没有找到任何东西的gem/插件。 有没有人为此创造了一个gem?

我在人们付费下载某些文件的网站上完成了这个,文件存储在RAILS_ROOT/private 。 首先要知道的是,您希望Web服务器处理发送文件,否则您的应用程序将被阻止传输大文件,如果您有任何类型的下载量,这将很快使您的网站停止运行。 因此,如果您需要在控制器中检查授权,那么您还需要一种方法将下载控制权传递回Web服务器。 执行此操作(我知道)的最佳方法是X-Sendfile标头,它由Nginx,Apache(带模块)和其他人支持。 配置X-Sendfile后,当您的Web服务器从您的应用程序收到X-Sendfile标头时,它会接管将文件发送到客户端。

一旦你的Web服务器使用X-Sendfile,这样的私有控制器方法是有帮助的:

 ## # Send a protected file using the web server (via the x-sendfile header). # Takes the absolute file system path to the file and, optionally, a MIME type. # def send_file(filepath, options = {}) options[:content_type] ||= "application/force-download" response.headers['Content-Type'] = options[:content_type] response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filepath)}\"" response.headers['X-Sendfile'] = filepath response.headers['Content-length'] = File.size(filepath) render :nothing => true end 

然后您的控制器操作可能如下所示:

 ## # Private file download: check permission first. # def download product = Product.find_by_filename!(params[:filename]) if current_user.has_bought?(product) or current_user.is_superuser? if File.exist?(path = product.filepath) send_file path, :content_type => "application/pdf" else not_found end else not_authorized end end 

显然,您的授权方法会有所不同,如果您提供的文件不是PDF,或者您希望在浏览器中查看文件(摆脱application/force-download内容类型),则需要更改标题。

您可以使用Amazon S3。 您可以使用控制器生成并提供安全区域后面的URL,并且它还具有一个function,该function基本上使资源在生成URL后仅在一定时间内可用。

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

nginx不支持AFAIK,X-SendFile。 Nginx有自己的扩展允许这个,称为X-Accel-Redirect。

您可以在此处找到有关此内容的更多信息: https : //www.nginx.com/resources/wiki/start/topics/examples/xsendfile/

在github上还有一个rails插件实现这个function: goncalossilva / X-Accel-Redirect

如果您想将内容交付与Rails身份validation和授权系统联系起来,那么您基本上必须将内容放在控制器后面。

如果您正在查看更简单的登录方法,则可以使用HTTP身份validation和托管环境中的设置(例如,使用htaccess)来处理它。

使文件在不可预测的URL上可用是目前在某些生产系统中使用的简单解决方案。

例如:GitLab。 以下图像上传到私人存储库的问题, https://gitlab.com/cirosantilli/test-private/issues/1 ,但您仍然可以看到它:

请注意,unguessable 90574279de前缀会自动添加到URL中。

Bitbucket(非Rails)也使用这种技术。