我试图用NGiNX和PHP来保护我的服务器上的文件(多种types)。
基本上我希望人们必须login到网站,如果他们想访问像图像这样的静态文件。 DropBox做得非常好。 他们强迫你login访问你放在那里的任何静态文件服务器。
我虽然关于使用NGiNX Perl模块。 而且我会写一个perl脚本来检查会话,看看用户是否login来让他们访问一个静态文件。
我宁愿使用PHP,因为我所有的代码都是在PHP下运行的,我不知道如何检查由PERL创build的PHP会话。
所以基本上我的问题是:如何保护需要用户login的任何types的静态文件,并使用PHP脚本创build有效的会话?
有两件事你问:
希望这可以澄清每个组件所起的作用 – 虽然可能有点过分。
防止外部访问文件:
这部分是由您的networking服务器完成的 – 在这里是nginx。
在你的nginxconfiguration(你的服务器块)中,指定一个rootpath。 默认情况下,该根path下的所有文件都可以直接访问。
例如,考虑以下(该域名是'example.com')
root /var/www/example.com/public_html
如果你有一个文件, uploaded_file.zip ,可以通过以下方式访问:
实际上,文档根目录之上的文件不能通过浏览器访问,但是大多数PHPconfiguration将允许您的代码读取文件并将其传递(对此的限制通常是由open_basedir引起的)
在某些情况下,最好将文件放在文档根目录下。 要做到这一点,仍然阻止(直接)外部访问,您将使用internal指令。 例如:
位置/上传{内部; }
现在,放置在/var/www/example.com/public_html/uploads中的任何文件只能在内部访问(即不能通过浏览器访问,但可以通过PHP脚本访问)。 如果需要,还可以在/ uploads位置上设置别名,以便可以使用另一个path来引用它。
在这一点上,你的文件不能直接访问,但你的脚本仍然可以提供服务。
用户身份validation和PHP:
考虑以下基本devise:用户可以直接访问文件,也可以进入login页面。 如果他们试图直接访问文件并login(并有权限),文件将下载,否则,它们将在login屏幕上结束。 要上传文件,用户需要login。
假设你的下载脚本(将把文件传递给用户的页面)被称为“download.php”。 一个典型的URL可能是example.com/download.php?file=uploaded_file.zip。 很有可能你不希望你的URL包含php文件名。 为了避免这种情况,你可以在你的nginxconfiguration文件中设置一个重写规则,这个规则将指向另一个位置(比如/ files)。 添加到你的nginxconfiguration:
rewrite ^/files/(.*) /download.php?file=$1 last;
(这等于改变以/ files开头的任何请求的请求path,并捕获/之后的所有内容,并将其作为查询parameter passing给你的php文件)。
现在,您的文件可以通过访问:example.com/files/uploaded_file.zip(内部redirect到您的PHP脚本)。
您的PHP文件(download.php)现在执行以下操作:
输出必要的标题(Content-Type,Content-Disposition等)并设置:
X-Accel-Redirect: /uploads/uploaded_file.zip;
注意,你可以完全从PHP下载(例如使用readfile ) – 它只是更有效一些,特别是对于大文件)通过nginx来完成。 另外,尽pipe用户似乎直接访问文件,但是在内部,它正在通过PHP,在允许它们继续之前validation它们。
URL -> nginx (redirect to PHP) -> PHP (authenticate) -> nginx (serve file)
在上传方面,你会将move_uploaded_file改为/var/www/example.com/public_html/uploads(受内部指令保护,所以不能直接访问文件),并保存数据库的权限。