安全显示上传了paperclip gem的图像

默认情况下:paperclip gem存储公共目录中的所有附件。

出于安全原因,我不想将附件存储在公共目录中,因此我将它们保存在应用程序根目录的uploads目录中:

 class Post < ActiveRecord::Base belongs_to :user has_attached_file :some_image, path: ":rails_root/uploads/:attachment/:id/:style/:filename" do_not_validate_attachment_file_type :some_image end 

我没有指定url选项,因为我不想为每个图像附件添加url。 如果指定了url:那么具有该url的任何人都可以访问该图像。 这不安全。

user#show页面中:我想实际显示图像。 如果我使用所有回形针默认值,那么我可以这样做,因为图像在公共目录中,图像将有一个URL:

 

Some image:

看来如果我将图像附件保存在公共目录之外并且没有指定URL(再次:执行此操作以保护图像),则图像将不会在视图中呈现。

我知道如何通过pundit gem在整个应用程序中进行授权。 但是,当该图像可公开访问时,授权图像是无用的。 因此,我尝试通过删除URL并将图像保存在公共目录之外来使图像无法公开访问,但随后图像不再在视图中呈现。

更新 :我的问题实际上归结为:我的图像保存在我的rails应用程序中。 使用回形针:有没有办法在视图中安全地显示图像? 换句话说:设置它使图像没有自己独立的URL(因为任何有该URL的人都可以访问该图像,使该图像不安全)。 以下是安全显示图像的一些示例:

  • 示例#1:仅在用户登录时显示图像。(图像没有自己独立的URL,因此没有其他方法可以访问图像)
  • 示例#2:仅在用户与此图像关联时显示图像。 (图像没有自己独立的url,因此没有其他方法可以访问图像)

附加更新 :我知道我可以安全地发送一个send_file文件,允许用户下载图像,但这不是我想要做的。 我不希望用户下载图像。 相反:我希望用户能够在网页上实际看到图像。 我想在页面上安全地显示/渲染图像。 使用send_file (据我所知)允许用户下载文件。 它不会在页面上呈现图像。

你可以使用send_file 。 假设您的路线中有secure_image动作:

 resources :posts do member do get :secure_image end end 

以及相应控制器中的以下方法:

 def secure_image send_file Post.find(params[:id]).some_image.path end 

您可以在视图中使用受保护的图像:

 <%= image_tag secure_image_post_path(@post) %> 

这里发生了什么:通常Rails(或nginxapache )为了速度而直接绕过安全检查发送静态文件。 但是对secure_image操作的请求通过整个Rails的堆栈,因此它受到您的身份validation系统的保护。

您可以在其中一个Rails控制器中执行操作,以validation用户的身份/权限以查看图像。 然后,操作可以使用send_file在其http响应中发送图像,而不是呈现视图:

http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file

然后,一旦您自己开始执行该操作,您就可以看到它在浏览器中显示图像,您可以创建指向该操作的URL的img标记。

每个图像都有自己的URL,但您可以完全控制该URL是什么以及谁可以访问它。

您可以将图像转换为Base64格式,而显示可以将图像转换为图像。

其他技术是为您的图像添加水印,以确保图像对其他人无用。