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

时间:2013-01-20 02:19:40

标签: php apache security .htaccess authentication

我有一个ADMIN脚本。

admin/index.php

所有活动都是通过此index.php文件完成的。
用户在获取程序功能之前登录。
$_SESSION['user_authenticated']已创建并设置为 true

admin/template/..

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

问题:

我需要保护admin/template/..目录中的所有内容免受直接访问
它应该只对经过身份验证的用户提供。

我想必须有一个.htaccess将请求重定向到check_session_auth_variable.php,查看$_SESSION['user_authenticated'] 还是 false 并且重定向到请求的文件会引发404错误

我知道最好的选择是将目录放在Web根目录之外,但在我的情况下,我需要按原样保留目录结构,而不进行修改。

3 个答案:

答案 0 :(得分:2)

好的,这是我的答案 - 而且最好的答案是'不'。但是images / 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);
            }
        }

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

那是'简单'的一部分;内容标题和mime类型必须'猜测'(我使用finfo作为mime类型,但它有一个错误,如2013年,这只会加剧问题)但即使是apache也不能100%正确地做到这一点...

然后删除图像的缓存控制标题,否则你不仅会经常作为php页面...

足以说;如果你有厚管道和你不需要的很多cpu循环,你只需要这样做......

答案 1 :(得分:1)

admin / .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
}

答案 2 :(得分:0)

我通常使用这个

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