默认情况下: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的任何人都可以访问该图像。这不安全。
在user#show
页面中:我想实际显示图片。如果我使用了所有的回形针默认设置,那么我可以这样做,因为图像将在公共目录中,而图像将一个网址:
<p>
<strong>Some image:</strong>
<%= image_tag @post.some_image %>
</p>
如果我将图像附件保存在公共目录之外并且未指定网址(再次:执行此操作以保护图像),则该图像将无法在视图中呈现。
我知道如何通过pundit gem在整个应用程序中进行授权。但是,当该图像可公开访问时,授权图像是无用的。因此,我尝试通过删除URL并将图像保存在公共目录之外来使图像无法公开访问,但随后图像不再在视图中呈现。
更新:我的问题实际上归结为:我的图片保存在我的rails应用程序中。使用回形针:有没有办法在视图中安全地显示图像?换句话说:设置它使图像没有自己独立的URL(因为任何有该URL的人都可以访问该图像,使该图像不安全)。以下是安全显示图像的一些示例:
其他更新:我知道我可以安全地发送一个send_file
文件,允许用户下载图片,但这不是我想要做的。我不希望用户下载图像。相反:我希望用户能够在网页上实际 查看 图片。我想安全 显示/渲染 页面上的图片。使用send_file
(据我所知)允许用户下载文件。它不会在页面上呈现图像。
答案 0 :(得分:9)
您可以使用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(或nginx
或apache
)为了速度而直接绕过安全检查发送静态文件。但secure_image
行动请求通过整个Rails&#39;堆栈,因此它受您的身份验证系统保护。
答案 1 :(得分:1)
您可以在其中一个Rails控制器中执行操作,以验证用户的身份/权限以查看图像。然后,操作可以使用send_file
:
http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file
然后,一旦您自己开始执行该操作,并且可以看到它在浏览器中显示图像,您就可以制作指向该操作的网址的img标记。
每个图片都有自己的网址,但您可以完全控制该网址是什么以及谁可以访问它。
答案 2 :(得分:0)
您可以将图像转换为Base64格式,而显示可以将图像转换为图像。
其他技巧是为您的图像添加水印,以确保图像对其他人无用。