ZF2:如何将安全图像作为网页的一部分提供

时间:2014-01-26 02:55:48

标签: php image-processing zend-framework2

我已经构建了一个包含用户个人资料的ZF2应用程序,我现在希望允许用户上传和显示他们的照片作为其个人资料的一部分。像你在LinkedIn中看到的那样。

上传照片似乎很容易(使用Zend\InputFilter\FileInput())。我的工作正常。

在我看来,将它们存储在Web根目录之外是很有意义的。 (例如,我不需要担心用户在目录上使用wget)。但是,如何将这些图像作为网页的一部分嵌入?

如果他们在网络根目录中,我只会<img width="140" src="/img/filename.jpg">,但显然如果他们在安全的位置,那是不可能的。解决方案是什么?

2 个答案:

答案 0 :(得分:4)

你是对的。 Web开发人员传统上模糊了用于存储图像的路径,以防止恶意个人批量检索它们(正如您在wget评论中提到的那样)。

因此,将用户的头像存储在/uploads/users/{id}.jpg中会很简单(并且不一定是不合适的,具体取决于您的用例),您可以使用方法来混淆URL。请记住:有两种方法可以解决问题。

更简单地说,您希望确保无法根据“公共”信息(例如,用户的主键)确定资产URL。因此,如果用户的用户ID为37,则访问其头像并不像下载/uploads/users/37.jpg那么简单。

更有力的方法是确保无法将URL与其公共信息相关联。像/uploads/users/37/this-is-some-gibberish.jpg这样的网址会将其所有权“展示”;负责此内容的用户必须是ID为37的用户。

一个简单的解决方案

如果您想采用更简单的方法,请根据set属性(例如,用户的ID)和应用程序范围的salt生成快速哈希。对于PHP,请查看"Fastest hash for non-cryptographic uses?"

$salt = 'abc123'; // Change this, keep it secret, store it as env. variable
$user->id; // 37
$hash = crc32($salt . strval($user->id)); // 1202873758

现在我们有一个唯一的哈希,可以在这个端点存储文件:/uploads/users/37/1202873758.jpg。无论何时我们需要引用用户的头像,我们都可以重复此逻辑来生成创建文件名所需的哈希值。

碰撞问题

您可能想知道,为什么我不能将它存储在/uploads/users/1202873758.jpg?这不会保证我的用户身份安全吗? (如果你不想知道,那没关系,我会为其他读者解释。)我们可以,但生成的哈希不是唯一的;如果用户数量足够多,我们会用其他用户的头像覆盖该文件,使我们的存储解决方案无法使用。

更隐秘

公平地说,/uploads/users/1202873758.jpg是一个更隐秘的文件名。也许甚至/uploads/1202873758.jpg会更好。存储包含这些路径的文件;我们需要确保唯一性,这不仅需要生成哈希,还需要检查唯一性,适应不可避免的冲突,并存储(可能已修改的)哈希 - 以及能够根据需要从存储中检索哈希。 / p>

根据您的应用程序堆栈,您可以通过无数种方式实现这一点,根据您的需要,某些方式比其他方式更合适,因此我不会在此处深入了解。

答案 1 :(得分:0)

如果您使用Zfcuser,则可以使用此模块:HtProfileImage

它包含一个非常容易显示图像的视图助手!