PHP保护目录免受直接的URL访问

我有一个ADMIN脚本。

admin/index.php 

所有的活动都是通过这个index.php文件完成的。
用户在访问程序function之前正在login。
$_SESSION['user_authenticated']被创build并设置为true

 admin/template/.. 

这个文件夹包含imagescssjavascript文件。
它们仅在此ADMIN中使用。 (仅在后端)

问题是:

我需要从admin/template/..目录中的所有内容被保护以防止直接访问
它应该只可用于经过身份validation的用户。

我想必须有.htaccessredirect请求check_session_auth_variable.php ,看起来如果$_SESSION['user_authenticated']假,redirect到请求的文件引发404错误

我知道最好的select是将目录放置在Web根目录之外,但是在我的情况下,我需要保持目录结构不变,无需修改。

管理员/的.htaccess:

 RewriteCond %{REQUEST_FILENAME} !check_auth.php RewriteCond %{REQUEST_FILENAME} -f RewriteRule .* check_auth.php?file=$0 [QSA,L] # pass everything thru php 

管理员/ check_auth.php:

 $file = $_GET['file']; if($_SESSION['user_authenticated']) { // please mind you need to add extra security checks here (see comments below) readfile($file); // if it's php include it. you may need to extend this code }else{ // bad auth error } 

好的,这是我的答案 – 最好的答案是“不”。 但是图像/ js / css在开发(在直播之前公开)和客户端预览中是相对重要的,这决定了我们不能执行基于IP的apache规则。 所以,规则(从上面略微修改)是

 RewriteEngine On # Exclude the public and error directories from authentication RewriteRule ^(public|error)($|/) - [L] # Perform authentication via php RewriteCond %{REQUEST_FILENAME} !auth.php RewriteCond %{REQUEST_FILENAME} -f RewriteRule .* auth.php?requested_file=$0 [QSA,L] 

(因为我需要一些内容确实是公开的子目录,请阅读:登录页面上使用的images / css / js)

和有关的PHP如下; 对于

  if($authenticated){ if($extension == 'php'){ call_user_func(function(){ $file_name = func_get_arg(0); $path = getcwd(); chdir(pathinfo($file_name,PATHINFO_DIRNAME)); return include($file_name); chdir($path); }, $file_name); } else { //set cache headers so the browsers don't have to refresh all the // static content header_remove('X-Powered-By'); header_remove('Transfer-Encoding'); header_remove('Cache-Control'); header_remove('Pragma'); header_remove('Expires'); //header('Expires:'); header('Content-type: '.$mime_type); readfile($file_name); } } 

这样做是执行php使用call_user_func()停止命名空间污染, include()执行PHP和chdir() ,以确保该脚本获取适当的当前工作目录。

这是'容易'的一部分; 内容头和MIME类型必须被“猜到”(我使用finfo作为MIME类型,但是它在2013年有一个bug,这只会加剧这个问题),但即使是apache也不能100% …

然后删除缓存控制标题的图像,否则你将不仅经常作为PHP网页以及…

足以说; 你只需要这样做,如果你有厚管道和很多你不需要的CPU周期…

我通常使用这个

 $redi_ext = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']; $php_verify = strpos($redi_ext, ".php"); if($php_verify !== false){ header('location: PAGE_NOT_FOUND_URL'); }