我想将所有内容重定向到:
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]
答案 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]