安全地显示使用回形针上传的图像 gem

Securely Display an Image Uploaded with paperclip gem

默认情况下:回形针 gem 将所有附件存储在 public 目录中。

出于安全原因,我不想将附件存储在 public 目录中,所以我将它们保存在应用程序根目录下的 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页面中:我想实际显示图像。如果我使用所有回形针默认值,那么我可以这样做,因为图像 将在 public 目录中 而图像 将具有 一个url:

<p>
  <strong>Some image:</strong>
  <%= image_tag @post.some_image %>
</p>

看来,如果我将图像附件保存在 public 目录之外并且不指定 url(同样:这样做是为了保护图像),那么图像将不会呈现在视图。

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

更新:我的问题归结为:我的图像保存在我的 rails 应用程序中。使用回形针:有什么方法可以在视图中安全地显示图像?换句话说:使图像没有自己单独的 url(因为拥有 url 的任何人都可以访问该图像,从而使该图像不安全)。以下是我所说的安全显示图像的一些示例:

其他更新:我知道我可以安全地发送带有 send_file 的文件,允许用户下载图像,但这不是我想要的在这里做。我不希望用户下载图像。相反:我希望用户能够实际 看到 网页上的图像。我想安全地 show/render 页面上的图像。使用 send_file (据我了解)允许用户下载文件。它不会在页面上呈现图像。

您可以在其中一个 Rails 控制器中执行一项操作,以验证用户的 identity/authority 以查看图像。然后,操作可以使用 send_file:

在其 http 响应中发送图像,而不是渲染视图

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

然后,一旦您让该操作自行运行并且您可以看到它在您的浏览器中显示图像,您可以制作指向该操作的 url 的 img 标签。

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

您可以使用 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' 堆栈,因此它受到您的身份验证系统的保护。

可以将图片转成Base64格式,显示的时候可以转成图片。

另一种技术是给您的图像加水印,以确保图像对其他人无用。