【问题标题】:mod-rewrite redirect but prevent direct accessmod-rewrite 重定向但阻止直接访问
【发布时间】:2017-07-26 12:18:46
【问题描述】:

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

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]

【问题讨论】:

  • 欢迎来到 Stack Overflow!您可能在编辑之前得到了一些反对意见,因为您最初的问题缺乏任何研究工作。我建议您使用welcome tour 并在help pages 上阅读有关asking good questions 的信息。

标签: .htaccess mod-rewrite


【解决方案1】:

在花费大量时间尝试解决此问题后,我发现解决方案在于记录不足的 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 文件(例如 /public/.htaccess),那么 @987654322 @ 并且用户将再次能够直接访问/public 中的文件。

关于变量和重定向的注意事项:

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

但是,对于那些您确实想知道如何到达特定 URI 的特殊场合,您可以使用 REDIRECT_STATUS。此外,重定向之前设置的任何环境变量(例如SetEnvIf)在重定向之后仍然可用,但with REDIRECT_ prefixed to the name of the variable(因此MY_VAR 变为REDIRECT_MY_VAR)。

【讨论】:

    【解决方案2】:

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

    www.example.com/public/file1/
    

    如果 prevent 你的意思是禁止,你可以添加一个规则来回复 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/

    真正对我有用的解决方案是将 secret 查询字符串附加到重定向并检查包含 /public/ 的 URL 上的此值:

    <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?


    如果您的 URL 应该有自己的查询字符串,例如 www.example.com/file1/?param=value,请务必添加标志 QSA

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

    【讨论】:

    • 我觉得这应该可以通过设置和测试 variable 而不是查询字符串来实现,但我似乎无法让它工作。
    • 哦,那真是太酷了@​​HullCityFan852 请随时编辑答案或评论您在此方面取得的任何成功!
    • 我终于让它工作了。请参阅my answer,以及有关变量和重定向的说明。
    • 干得好@HullCityFan852!
    猜你喜欢
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 2011-12-01
    • 2012-04-18
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多