保护图像- PHP base64 vs readfile


securing images - php base64 vs readfile

现在我使用base64来控制谁可以访问我网站上的图像。我将这些图像存储在webroot目录之外,因此没有人可以直接访问它们。然后,我通过他们在postgresql数据库中访问哪些记录来确定谁有权访问这些图像。基本上,如果他们可以查询记录"a",那么他们就可以看到图片"a"。

if (file_exists($pic)) {
    $imgbinary = fread(fopen($pic, "r"), filesize($pic));
    $picbase64 = "data:image/gif;base64," . base64_encode($imgbinary);
    echo('<img src="' . $picbase64 . '" />');

我如何使用readfile而不是base64,同时仍然保持我的安全性?例如,当使用readfile方法将图像传递到客户端浏览器时,这需要我使用$_GET方法向php脚本发送一个变量,该脚本具有readfile和头类型,然后在客户端浏览器上显示图像。问题是任何人都可以查看html源代码并看到<img src=phpscript.php?imagename=foo.jpg />,然后在他们的浏览器中使用任何他们喜欢的参数http://www.hostname/phpscript.php?imagename=bar.jpg调用脚本。对于base64方法,我目前使用这是不可能的,因为我不需要有一个单独的脚本来处理我的图像,它采用$_GET参数,而是图像直接嵌入在html页面中。

谢谢你的帮助!

编辑-对不起,伙计们,我没有提到也允许匿名访问,某些信息是公开的。这意味着如果你没有经过认证,你可以读取记录"a"你也可以看到图像"a"

您现在所做的与您需要做的之间的实质性区别是通过多个请求发送文件。这需要在请求之间验证或以其他方式记住用户。

你现在拥有的是:

if (file_exists($pic)) {
    // do stuff
}

你需要的是:

if (file_exists($pic) && user_has_image_permission($pic)) {
    // do stuff
}

所以你需要解决的细节是user_has_image_permission()函数背后的逻辑。

如果你需要这是安全的,我倾向于通过会话来解决这个问题,但你也可以使用cookie。

如果你不介意牺牲一些安全性来换取一点简单,你可以使用某种"url pass短语",就像那些通常用于在网络服务中共享文档和文件的短语,比如谷歌文档、AWS、私人RSS提要等中的"任何人都有链接"。

最后,您可以使用完全在PHP之外的基于http身份验证的解决方案。在Apache中,这采用访问控制的形式。

我同意;使用cookie检查访问将是最直接的方法。如果您希望加快速度,请搜索X-Sendfile。它可以卸载文件传输到您的web服务器一旦他们已经被认证。它内置在lighttpd中,并且有一个apache mod https://tn123.org/mod_xsendfile/.