【问题标题】:Advantages and disadvantages of BLOBS (security)BLOBS(安全)的优缺点
【发布时间】:2014-04-30 09:43:13
【问题描述】:

一年前,当我使用简单的 MySQL 数据库为人们创建简单的 PHP 站点时,我从小就认为将整个图像存储在数据库中是可能的,但这是一个糟糕的想法。相反,您应该将图像存储在文件系统中,并将图像路径简单地存储在数据库中。尽管我缺乏经验,但我从一开始就同意这一点。当您将数据库备份到外部服务时,它必须保持数据库轻便,并在实际本地使用时使其更快。然而,后面这点完全是猜测,我希望有人澄清我的理论:

当您将与数据库中的对象关联的图像存储为 BLOB 时,当您请求此对象时,是否将整个对象及其属性(包括大量图像信息)写入内存,即使在不需要时也是如此?例如

2.0.0p247 :001 > Object.column_names
 => ["id", "name", "blob"] 
2.0.0p247 :001 > Object.first.blob 
 => # not sure what this will return! I'm guessing a matrix-like wall of image information?
2.0.0p247 :003 > Object.first.name
  User Load (0.8ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
 => "Kitty" 

我了解调用Object.first.blob 将花费相对较长的时间,因为我们正在检索大量图像信息。但是Object.first.name 是否会花费相同的时间,因为Object.first 将所有内容、id、name 和blob 都写入内存? 如果这个问题的答案是肯定的,那就是从不使用 BLOBS 的一个很好的理由。但是,如果答案是否定的,并且 rails 足够聪明,可以只将请求的属性写入内存,那么 BLOBS 突然变得非常有吸引力。

老实说,我真的很担心你会说将图像存储在 BLOB 中既好又好。它会让事情变得容易得多。备份将很简单。在一次“模块化”上传中备份站点的动态内容会感觉非常好,而不是诉诸一些复杂的whenever 增强 rake 任务来确保路径及其各自的图像被上传到外部位置。

更是如此绝对不可能使用 Rails 将某些图像设为私有。我搜索得很高,我搜索得很低,我在这里问过。得到了一些支持,但没有可靠的回应。网上没有教程。没有。关于如何在资产文件夹中存储图像的教程包,但没有将图像设为私有。

假设我有三种类型的用户,typeA、typeB 和 typeC。假设我有三种类型的图像。所以数据库模式如下:

图片

=> ["image_path","blob","type"]

用户

=> ["name","type"]

我想要的是用户只能请求以下内容:

类型A:

只能查看 A 类型的图像

无法查看 B 类型的图像

不能只查看 C 类型的图像

类型B:

只能查看 B 类型的图像

无法查看 A 类型的图像

不能只查看 C 类型的图像

typeC:

只能查看 C 类型的图像

无法查看 A 类型的图像

不能只查看 B 类型的图像

是的,我可以用两种类型的用户和图像给你一个例子,但我真的想确保你理解这个问题;我想到的实际系统将有数百个types。

就像我说的,非常简单的想法,但我发现使用 rails 是不可能的,因为所有图像都存储在公共文件夹中!所以typeB 用户只需输入/assets/typeAImage.jpg 就可以了!哎呀,即使不是用户也可以做到。

send_file 方法对我不起作用,因为我不是按 sae 将图像作为下载发送给他们,而是在视图中向他们展示图像。*

现在,如果图像存储在数据库中,使用 BLOBS 将非常巧妙地解决这个问题。我不确定实际的语法,但我可以在用户视图中做这样的事情:

<% if current_user.type == image.type do %>
   <%= image_tag image.blob #=> <img src="/assets/typaAImage.jpg" alt="..." class="...">  %>
<% end %>

是的,你可以用路径做同样的事情:

<% if current_user.type == image.type do %>
   <%= image_tag image.path #=> <img src="/assets/typaAImage.jpg" alt="..." class="..."> %>
<% end %>

但就像我说的,即使不是用户也可以简单地请求/assets/typeAImage.jpg。 如果存储在 BLOB 中,则无法执行此操作。

结论:

  1. popplers BLOBS 有什么问题?我在 Heroku 上运行一个 postgres 数据库,每秒有几十个用户。所以是的,不是Facebook,但也不是Allegory on the Pointless of Life,所以性能很重要。他们还拥有强大的移动追随者,因此速度至关重要。使用 BLOBS 会与此冲突吗?

  2. 如何在视图中显示存储在 BLOB 中的图像?

  3. 为了确认一下,BLOBS 将允许我通过 https 向某些成员安全地显示安全的秘密图像?

  4. 数据库备份速度怎么样?这会受到打击,但无论如何我都想备份图像,而且这是每晚的事情,所以谁在乎它是否很慢?对吧?

  5. 只要备份是加密的,图像就会是安全的,对吗?就像密码在数据库中存储为哈希一样,我是否也应该以加密格式存储我的超级机密 BLOBS?我想是的......你认为bcrypt 能胜任这项任务吗?我不明白为什么不。

  6. BLOBS 是否被认为是业余和懒惰的?

...最后加分(可能超出问题的范围):

*= 当我写这篇文章时,我在想'是的,但是在视图中显示图像是将图像下载给他们。那么send_file方法能不能按照我描述的方式创建私有镜像,使用文件系统存储镜像呢?

【问题讨论】:

  • 听起来您更关心 Rails 对 bytea 字段的限制(假设这就是您所说的“blob”),而不是与数据库本身有关的任何事情。

标签: ruby-on-rails postgresql blob


【解决方案1】:

回答第一个问题:是的,在 Rails 中可以延迟加载某些属性,但默认情况下 Active Record 不支持它There is a gem for this though。 (DataMapper 默认支持这个,还有plugin for Sequel)。

对于第二部分:您的方法的最大缺点是性能。资产最好通过快速、静态的 Web 服务器提供服务,该服务器可以从文件系统加载文件,而不是通过动态应用程序。不建议阻塞数据库服务器来查询大型 Blob,尤其是因为扩展数据库比扩展文件系统要困难得多。

最后一部分:您可以使用多种选项对用户隐藏文件,并仅在需要时提供它们。其中一个选项是X-SendFile 或X-Accel-Redir,您可以在其中指定Rails 中返回的标头内的文件名,并且代理请求的Web 服务器(并且也支持此标头)将选择它,并且提供该文件。这不是重定向,因此 URL 仍然是相同的,并且该文件仍然可以隐藏,无法正常访问。当然,为此,您必须通过网络服务器将您的请求代理到 rails,这通常至少在负载平衡级别已经发生,或者如果您正在使用乘客。

另请注意,您也可以在提供普通资产文件时tell Rails to send X-SendFile headers。

Also see this answer.

【讨论】:

  • 我正在使用 Heroku,我能做到这一切吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 2015-05-01
  • 2013-04-07
  • 2010-09-29
相关资源
最近更新 更多