从根 .htaccess 重写规则中排除目录以允许其受到密码保护?

从根 .htaccess 重写规则中排除目录以允许其受到密码保护?

上周我花了大量时间试图解决这个问题,但无论我怎么努力,我都无法让它工作。我的网络托管商说他们没有人对 .htaccess 文件有足够的了解,无法让它工作(令人鼓舞,对吧?),我从其购买 CMS 的公司也无法确定解决方案。我也在这里和其他网站上阅读了数十个答案,但我就是无法解决我的问题。

情况是这样的:我的 CMS - Invision Power Board - 生成以下 .htaccess 文件,该文件位于网站的根目录中:

<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

我有一个子目录sub_dir,我需要使用子目录中的 .htaccess 文件对其进行密码保护。我通过 cPanel 设置了密码保护,如果网站根目录中的 .htaccess 文件被禁用,它就可以正常工作。但是,如果网站根目录中的 .htaccess 文件未被禁用,那么当我浏览到sub_dir主页时就会显示。起初我以为显示的主页可能与 404 页面重写有关,但即使我删除了 404 页面的重写条件和规则,主页仍然会显示。

.htaccess文件中的代码sub_dir为:

AuthUserFile "/home/[user]/public_html/.htpasswd"
AuthType Basic
AuthName "subdir"
require valid-user

正如我之前提到的,当根目录中的 .htaccess 文件被禁用时,密码保护会起作用。当我删除底部的重写条件和规则(index.php 的行)时,它也起作用,但删除 404 页面的重写条件和规则不会影响任何东西。

我尝试了几十种可能的解决方案,但都没有奏效。举几个例子,我尝试了下面 Poncha 的答案:

RewriteCond %{REQUEST_URI} !^sub_dir

我也尝试过这个:

RewriteRule ^/sub_dir  - [L]

还有很多很多我现在都不记得的事情。关键是,到目前为止什么都没起作用。我也尝试了所有可能的组合,包括前斜杠和后斜杠。

我的服务器正在运行 Apache 2.2.22。

我真的束手无策了。请帮帮我。

答案1

看起来你已经尝试过了,这是最明显的答案(正如 poncha 指出的那样),并且很可能最有可能出现在 mod_rewrite 教程/指南中。通过使用 排除目录RewriteCond,注意条件的匹配与 相对应%{REQUEST_URI},它以 开头/“:

<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/sub_dir
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]

RewriteCond %{REQUEST_URI} !^/sub_dir
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

编辑:

RewriteRule看看你尝试过的方法,这也是错误的。当它在 htaccess 文件中时,你不希望在匹配中使用前导斜杠:

<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On

RewriteRule ^sub_dir  - [L]


RewriteBase /
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

答案2

如果请求的路径不是现有文件,也不是现有目录,则此规则转发到主页。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

显然,因为您被转发到主页,所以服务器认为该sub_dir目录不存在,或者请求sub_dir被重定向到不存在的内容。

在这种情况下,首先要检查的是,这是否sub_dir是一个实际的目录,请记住,目录名称将取决于您的区分大小写在大多数运行 Apache 的情况下,同时要记住符号链接不是一定与目录同等对待。

答案3

您不妨尝试在sub_dir.htaccess 中执行以下操作以禁止 modrewrite 传播到您的sub_dir

    ## turn off rewrite engine
    RewriteEngine Off
    ## now do your auth stuff
    AuthUserFile "/home/[user]/public_html/.htpasswd"
    AuthType Basic
    AuthName "subdir"
    require valid-user

如果您确实需要在 sub_dir 中运行重写规则,那么请在 .htaccess 文件中专门执行这些规则,这样就不会产生任何混淆。一旦您执行 RewriteEngine On/Off,父文件夹中的规则就不会直接应用。它们首先从该文件夹读取,然后从根文件夹读取。

答案4

上述解决方案不起作用,因为它们没有解决根本问题,即要从规则中排除的子文件夹受密码保护。

当 Apache 拒绝初始访问并显示登录对话框时,重写规则会启动,但无法将客户端重定向到可访问的文件,因此会出现 404 错误。为了解决这个问题,我们需要提供一个“虚拟”文件,当初始访问尝试失败时,客户端可以重定向到该文件。

ErrorDocument 401 /failed_auth.html
RewriteCond %{REQUEST_URI} ^/pwd-protected-sub-folder/(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^/failed_auth.html$
RewriteRule ^.*$ - [L]

相关内容