编辑HTACCESS文件以防止直接访问特定文件夹中的特定文件

时间:2015-06-07 12:48:07

标签: php .htaccess mod-rewrite redirect subdirectory

我试图阻止直接访问子文件夹中的特定文件。

我意识到在这个论坛上有很多主题描述了类似的问题。但是,由于我已经存在的HTACCESS文件,我似乎有点尴尬........

以下是文件的文件路径:

www.example.com/PRINCIPAL/PROJECTS/my_file.php

my_file.php 是我要通过直接访问限制的文件)

我的意思是:my_file.php只有当用户浏览我网站内的特定事件序列时才能访问当前(例如:选择这里的单选按钮........点击那里的另一个按钮,等等)

我希望它保持这种状态。

不幸的是,如果用户试图直接访问该文件,通过在浏览器中输入URL,他也可以访问 my_file.php

这是我不想要的。

我说我的情况相当尴尬的原因是:通常情况下,这很容易解决:

(a)在HTACCESS文件中包含一条规则,该规则会阻止直接访问文件本身 (b)将文件放在单独的文件夹中,然后在htaccess文件中使用DENY ALL (c)将文件放在单独的文件夹中,然后在其旁边创建一个EMPTY INDEX文件

依此类推,等等

之所以这些都不适合我的原因是----正如我上面提到的----由于我当前的HTACCESS文件。它已经包含两个规则:

(a)删除所有PHP文件扩展名的规则 (b)隐藏子文件夹的规则" PROJECTS"从视图(在浏览器栏中)

这是我目前的HTACCESS文件:

 Options -Indexes
 Options -MultiViews
 Options +FollowSymlinks

 <IfModule mod_rewrite.c>

 RewriteEngine On

 RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/?([^/]+)/([^/]+)/([^.]+)\.php [NC]
 RewriteRule ^ /%1/%3 [R=301,L]

 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^([^/]+)/([^/]+)/?$ $1/PROJECTS/$2.php [NC,L]

 </IfModule>

所以,正如我前面提到的,这是my_file.php的路径:

www.example.com/PRINCIPAL/PROJECTS/my_file.php

在我的HTACCESS文件中使用这两个规则,实际的文件路径变为:

www.example.com/PRINCIPAL/my_file

因此,我在上面列出的3个解决方案---- A,B和C ---对我不起作用。

我无法在网上找到解决我特定问题的任何内容。我还是新手,但我猜我需要:

(a)以某种方式修改我当前的HTACCESS文件 (b)创建一个新的单独的HTACCESS文件,并将其与my_file.php一起放在一个单独的文件夹中

非常感谢任何帮助

由于

更新

我应该提到:&#34; my_file.php&#34;在新窗口中打开(子窗口)。我已经通过使用 $ _ SESSION变量来检查用户是否进行了特定的必要选择来解决问题。不幸的是,它没有用。当我检查错误日志时,我看到了以下消息: UNDEFINED INDEX XXXXX

显然,当打开子窗口时,会话变量不会被转发(这很奇怪)

更新

以下是父页面的代码:

  if(isset($_POST['submit'])  {

  $_SESSION['response'] = $_POST['selection'];

(用户必须选择单选按钮,才能继续)。

然后,在子窗口的顶部,我有这个代码:

if (!(isset($_SESSION['login']) && $_SESSION['login'] != '') ||    
   (isset($_SESSION['login']) && !(isset($_SESSION['response']))

{

header ("Location: /PROJECTS/access_denied");

第一部分检查以确保用户已登录。

第二次检查以确保在上一页确实选中了单选按钮。

更新

再次,我应该提到的一点:(我的头现在到处都是)。子窗口是一个问卷调查程序;它一次一个地问一系列问题。每次询问新问题时,窗口都会刷新。它是SAME php文件(my_file.php)。它每次都会刷新,但会显示一个新问题,具体取决于用户在每个上一页上选择的内容。

出于这个原因,$ _SESSION&#34; 检查&#34;每次子窗口刷新时,都需要有效。

如果我在第一个子窗口开头的 UN-SET 会话,下一个问题将显示&#34; Access_Denied&#34;页面!

并且,您可能会问:为什么还要在儿童窗口打开这个问卷调查计划?好吧,除了其他原因,我禁用了&#34;后退按钮&#34;和&#34;页面刷新&#34;在这个子窗口上,因为一旦问卷开始,用户不刷新此窗口是很重要的。

修改

作为最后的手段,我想我可以从URL地址栏中隐藏文件名(my_file),这样用户就不知道文件的名称,因此,我不知道实际上是在寻找它。

我尝试将文件名更改为&#34; index.php&#34;,但这仍显示在地址栏中。

我尝试了很多方法来隐藏文件名,但似乎没有任何工作

1 个答案:

答案 0 :(得分:2)

恕我直言,只有当用户以特定的方式到达那里时才允许访问PHP文件是不正确的方法。 Web服务器上的文件应始终可公开访问或不公开(有时不是,有时不是)。

我的建议是收集有关用户使用方式的信息。例如,您可以在会话中存储这些数据,然后在调用my_file.php时对其进行分析。如果你应该观察,用户已经采取了'#34;权利&#34;到目前为止,您可以像往常一样执行脚本。如果没有,您应该显示错误消息,或 - 如果您想 - 告诉他,他没有访问权限。

假设您想为此目的使用会话,可以将以下代码放在my_file.php之上:

session_start();
if (!isset($_SESSION['login']) || ($_SESSION['login'] == '') || 
    !isset($_SESSION['response']))
{
    header ("Location: /PROJECTS/access_denied");
    exit;
}

//Process the request, as the user is now confirmed to be allowed to use this page

//In the end, possibly:
unset($_SESSION['response']);
//Now the user won't be able to use this page again until he "took the right way" again.

在您的父页面中,您将使用:

session_start();  
if(isset($_POST['submit'])  {
    $_SESSION['response'] = filter_input(INPUT_POST,'selection');
    //...
}

// I assume, that $_SESSION['login'] is set somewhere else.

这只是一个非常基本的例子。我认为关键是收集有关用户如何访问脚本的信息。

当不使用会话时,可能会考虑检查$_SERVER['HTTP_REFERER']以检查用户来自哪里,但是您应该记住,由于隐私考虑因素,许多用户都不会发送此信息。更重要的是,客户可以将引用设置为任意值,因此这绝对不是正确的方法。

编辑:插入代码以便在示例中使用会话。你还记得在这两个页面上打电话给session_start()吗?我认为开头的if声明搞砸了一点,所以我试着更简单。 :)此外,我在阅读POST变量时使用filter_input作为一个非常基本的安全增强功能。