mod-rewrite重定向但阻止直接访问

时间:2017-07-26 12:18:46

标签: .htaccess mod-rewrite

我想将所有内容重定向到:

www.example.com/public/...

但阻止直接访问

www.example.com/public/file1/
www.example.com/public/file2/
etc

最终的网址应为:

www.example.com/file1/

我已尝试将其用于重定向并且有效 - 但我不知道如何阻止直接访问:

ReWriteCond %{REQUEST_URI} !/public/
RewriteRule ^(.*) public/$1 [L]

2 个答案:

答案 0 :(得分:2)

在花了大量时间试图解决这个问题之后,我发现解决方案在于记录不足的REDIRECT_STATUS environment variable

将此添加到您的顶级/.htaccess代码的开头,以及您之下的所有.htaccess个文件(例如/public/.htaccess):

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{ENV:REDIRECT_STATUS} !=200
RewriteRule ^ /public%{REQUEST_URI} [L]

</IfModule>

现在,如果用户请求example.com/file1,则会在/public/file1处为其提供文件。但是,如果他们直接请求example.com/public/file1,则服务器将尝试在/public/public/file1处提供文件,这将失败(除非您碰巧在该位置有文件)。

重要:

您需要将这些行添加到所有.htaccess个文件中,而不仅仅是Web根目录中的顶级文件,因为如果您在Web根目录下面有任何.htaccess个文件(例如{{1 }})然后these will override the top-level .htaccess,用户将再次能够直接访问/public/.htaccess中的文件。

请注意变量和重定向:

执行重定向(或重写)causes the whole process to start again with the new URI,因此之后不再设置在重定向之前设置的任何变量。这是故意做的,因为通常你不希望最终的结果取决于你是如何到达那里的(即是通过直接请求还是通过重定向)。

但是,对于想知道如何访问特定URI的特殊情况,您可以使用/public。此外,重定向之前设置的任何环境变量(例如,使用SetEnvIf)在重定向后仍然可用,但是with REDIRECT_ prefixed to the name of the variable(因此REDIRECT_STATUS变为MY_VAR)。

答案 1 :(得分:1)

也许您应该澄清当用户尝试访问真实网址时的预期行为:

www.example.com/public/file1/

如果通过阻止表示禁止,则可以添加规则以使用403

进行回复
<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_URI} !/public/
RewriteRule ^(.*)$ /public/$1 [L]

RewriteCond %{REQUEST_URI} /public/
RewriteRule ^(.*)$ / [R=403,L]
</IfModule>

更新:上述解决方案无效!

我意识到我之前的解决方案总是抛出403,所以它毫无价值。实际上,这有点棘手,因为重定向本身在URL中确实包含/public/

真正适合我的解决方案是在重定向中附加机密查询字符串,并在包含/public/的网址上检查此值:

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_URI} !/public/
RewriteRule ^(.*)$ /public/$1?token=SECRET_TOKEN [L]

RewriteCond %{REQUEST_URI} /public/
RewriteCond %{QUERY_STRING} !token=SECRET_TOKEN
RewriteRule ^(.*)$ / [R=403,NC,L]
</IfModule>

这种方式www.example.com/file1/会显示file1,但www.example.com/public/file1/会抛出403 Forbidden错误响应。

此处讨论了对此SECRET_TOKEN安全性的疑虑:How secure is to append a secret token as query string in a htaccess rewrite rule?

如果您的网址需要拥有自己的查询字符串,例如www.example.com/file1/?param=value,请务必添加标记QSA

RewriteRule ^(.*)$ /public/$1?token=SECRET_TOKEN [QSA,L]