使用PHP/Apache限制对静态文件的访问(html,css,img等)

Bar*_*art 38 php apache security .htaccess

假设您在服务器上的目录中有很多html,css,js,img等文件.通常,只需输入完整的URL就可以访问Internet-land中的任何用户:http://example.com/static-files/sub/index.html

现在,如果您只希望授权用户能够加载这些文件,该怎么办?对于此示例,假设您的用户首先从以下网址登录:http://example.com/login.php

您将如何允许登录用户查看index.html文件(或"static-files"下的任何文件),但将文件限制为其他所有人?

到目前为止,我已经提出了两种可能的解决方案:

解决方案1
在"static-files"下创建以下.htaccess文件:

Options +FollowSymLinks  
RewriteEngine on  
RewriteRule ^(.*)$ ../authorize.php?file=$1 [NC]
Run Code Online (Sandbox Code Playgroud)

然后在authorize.php中......

if (isLoggedInUser()) readfile('static-files/'.$_REQUEST['file']);
else echo 'denied';
Run Code Online (Sandbox Code Playgroud)

这个authorize.php文件大大简化了,但你明白了.

解决方案2
在"static-files"下创建以下.htaccess文件:

Order Deny,Allow
Deny from all
Allow from 000.000.000.000
Run Code Online (Sandbox Code Playgroud)

然后我的登录页面可以为每个登录的用户附加带有IP的.htaccess文件.显然,这还需要某种清理例程来清除旧的或不再使用的IP.


我担心我的第一个解决方案在服务器上会变得相当昂贵,因为他们访问的用户和文件的数量会增加.我认为我的第二个解决方案会便宜得多,但由于IP欺骗等原因也不太安全.我还担心如果有很多同时用户,将这些IP地址写入htaccess文件可能会成为应用程序的瓶颈.

哪些解决方案听起来更好,为什么?或者,你能想到一个完全不同的解决方案,它会比其中任何一个更好吗?

Sha*_*ane 35

我会考虑使用PHP加载程序来处理身份验证,然后返回您需要的文件.例如,而不是做<img src='picture.jpg' /> 类似的事情<img src='load_image.php?image=picture.jpg' />.

您的图像加载程序可以验证会话,检查凭据等,然后决定是否将所请求的文件返回到浏览器.这将允许您将所有安全文件存储在Web可访问的根目录之外,这样任何人都不会只是WGET它们或"意外地"浏览它们.

只记得在PHP中返回正确的标题,并在php中执行类似readfile()的操作,并将文件内容返回给浏览器.

我在几个大型安全网站上使用了这个设置,它就像一个魅力.

编辑:我当前正在构建的系统使用此方法加载Javascript,图像和视频但CSS我们并不担心安全.

  • 谢谢谢恩.这个加载器基本上是我在第一个解决方案中描述的.我对它的关注是服务器费用,但我很高兴听到它在你的"大型安全网站"中对你有用. (2认同)

Den*_*isS 7

X-SENDFILE

有一个用于Apache(和其他HTTP服务器)的模块,它允许您告诉HTTP服务器提供您在PHP代码的标头中指定的文件:所以您的PHP脚本应如下所示:

// 1) Check access rights code
// 2) If OK, tell Apache to serve the file
header("X-Sendfile: $filename");
Run Code Online (Sandbox Code Playgroud)

2个可能的问题:

  1. 您需要访问重写规则(启用.htaccess或直接访问配置文件)
  2. 您需要将mod_xsendfile模块添加到您安装的Apache中

在另一个帖子中,这是一个很好的答案:https: //stackoverflow.com/a/3731639/2088061

  • 这绝对是这个问题的最佳解决方案。 (2认同)

Pek*_*ica 5

我一直在思考同样的问题.我同样不满意为每个服务的小资源运行的PHP引擎.几个月前我在这里问过同样的问题,但重点不同.

但我只是有一个非常有趣的想法,可能会奏效.

  • /sessions在Web服务器上维护一个名为somewhere 的目录.

  • 每当用户登录时,创建一个包含会话ID的空文本文件/sessions.例如123456

  • 在您的PHP应用程序中,提供如下图像: /sessions/123456/images/test.jpg

  • 在您的htaccess文件中,有两个重定向命令.

  • 一个转化 /sessions/123456/images/test.jpg/sessions/123456?filename=images/test.jpg

  • 第二个捕获任何调用//sessions/(.*)并使用该-f标志检查指定文件是否存在.如果/sessions/123456不存在,则表示用户已注销或其会话已过期.在这种情况下,Apache发送403或重定向到错误页面 - 资源不再可用.

这样,我们在mod_rewrite中进行准会话认证只做一个"文件存在"检查!

我没有足够的例程来动态构建mod_rewrite语句,但它们应该很容易编写.(我希望你的方向@Gumbo :)

注意事项和警告:

  • 必须使用cron作业快速删除过期的会话文件,除非可以在.htaccess中检查文件的mtime(这很可能).

  • 只要会话存在,图像/资源就可供任何客户端使用,因此没有100%的保护.您可以通过将客户端IP添加到等式(=您创建的文件名)中来解决此问题,并对%{REMOTE_ADDR}进行额外检查.这是先进的.htaccess掌握,但我很确定它是可行的.

  • 资源URL不是静态的,每次登录时都必须检索,因此不需要缓存.

我对这方面的反馈感兴趣,我可能忽略的任何不足或不可能,以及任何成功的实施(我现在没有时间自己设置测试).