我目前正在努力使 nginx 仅保护文件夹名称,而与其中的文件名无关。假设我正在访问文件夹 /one/two/three 中的文件,它看起来像这样:
http://example.com/one/two/35d6d33467aae9a2e3dccb4b6b027878/file.mp3
因此文件夹“三”只能由目录 md5 访问,而实际路径将返回 403。我有数千个这样的文件夹,所以我需要将它们隐藏起来,但可以通过只知道 md5 的远程客户端对它们进行静态访问运行。
同时,这样的链接也应该起作用:
http://example.com/one/two/35d6d33467aae9a2e3dccb4b6b027878/four/file.mp3
所以只有一个特定的目录级别是隐藏的。
您可以通过使用您想要保护的隐藏文件夹或文件的内部位置以及检查您的散列代码是否允许访问您的文件的方法来实现这一点。
Nginx 不允许直接访问您的隐藏文件(例如 /protected/folder1/folder2/file.pdf),因为该位置已被标记为内部。但是您的脚本可以使用特殊标头X-Accel-Redirect 重定向到此位置。
因此,您可以让 Nginx 做它最擅长的事情,交付数据,并且您的脚本仅检查是否允许访问。
下面你可以看到一个简单的例子。
文件夹 /data 包含公共内容(例如公共图像)。非公开图像存储在不同的文件夹(在 htdocs 之外)并通过位置 /protected_data 提供。此位置具有包含受保护图像的文件夹的别名和内部指令。所以这是无法从外部访问的。
在 PHP 脚本中,我首先检查了受保护的文件是否存在。这可能是一个安全问题,但通常检查用户权限比简单的 file_exists 成本更高(耗时)。因此,如果安全性比性能更重要,您可以切换检查的顺序。
Nginx 服务器配置:
PHP 脚本:
为了使这成为可能,nginx 需要能够判断哈希
35d6d33467aae9a2e3dccb4b6b027878
对应于three
. Nginx 到今天还不能做到这一点(我认为它不在待办事项列表中)。我可以想象如何实现类似的唯一方法是将文件托管在另一个位置,并在创建文件时使用目标目录的哈希作为您所在位置根目录中的链接名称创建符号链接/上传。
例如,您的网络服务器位置
http://example.com/one/two/
指向一个目录(例如/var/www/html/
),其中符号链接35d6d33467aae9a2e3dccb4b6b027878
指向three/
位于另一个位置(例如/var/www/protected/
)的目录。上传需要触发脚本或类似的东西才能在 中创建文件夹
three/
,/var/www/protected/
散列“三”,然后创建符号链接/var/www/html/35d6d33467aae9a2e3dccb4b6b027878
。这是我能想到的唯一方法。