【问题标题】:mod_rewrite: allow redirect but prevent direct accessmod_rewrite:允许重定向但阻止直接访问
【发布时间】:2011-08-11 18:50:49
【问题描述】:

我目前正在使用 mod_rewrite 进行内部重定向

RewriteCond  %{REQUEST_URI}  ^/pattern$
RewriteRUle .* file.php

但是,我想通过将对该文件的请求重定向到未找到的页面 URL 来防止直接访问 file.php

RewriteCond %{REQUEST_URI} /file.php
RewriteRule .* page-not-found.php

问题是,当我进行第一次重定向时,第二条规则也适用,因此会破坏我的第一次内部重定向。

[Q] 有没有办法允许第一次重定向但阻止直接访问重定向的文件?

【问题讨论】:

    标签: apache mod-rewrite redirect


    【解决方案1】:

    使用ENV:REDIRECT_STATUS 变量(参见mromainecontribution"Hidden features of mod_rewrite" community wiki

    RewriteCond  %{REQUEST_URI}  ^/pattern$
    RewriteRule .* file.php
    
    # Redirect direct access to file.php
    RewriteCond %{REQUEST_URI} /file.php
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule .* page-not-found.php
    

    测试用例:

    每个 HTTP 响应都是 HTTP 200。

    【讨论】:

    • +1 for RewriteCond %{REQUEST_URI} /file.phpRewriteCond %{ENV:REDIRECT_STATUS} ^$ 这为我解决了一个问题。谢谢!
    • 每个客户端会话是否存储环境?我的意思是在多个请求可能同时到达时使用它们是否安全?
    • 我认为环境变量是每个请求的,尤其是这个由内部 Apache 进程填充的 (ENV:REDIRECT_STATUS)。
    【解决方案2】:

    编辑: 受@AndrewR 的回答启发(目前的形式似乎对我不起作用 - 看起来第二条规则仍然适用。)一个 .htaccess 唯一的解决方案使用密钥。

    如果遇到有效模式,请在查询字符串中添加密钥。

    然后在决定页面重定向时测试该密钥。

    RewriteEngine on
    Options +FollowSymlinks
    
    RewriteCond  %{REQUEST_URI}  ^/pattern$
    RewriteRule .* /file.php?SUPER_SEKRIT_KEY [QSA]
    
    RewriteCond %{QUERY_STRING} !SUPER_SEKRIT_KEY
    RewriteCond %{REQUEST_URI} /file.php
    RewriteRule .* /test/page-not-found.php [L,F]
    

    当然要使用更复杂的键,并且仅用于内部重定向!否则,用户将能够获取密钥。

    【讨论】:

    • 使用带有 E 标签的环境变量代替密钥可能不那么具有侵入性(不更改可能稍后使用的 QUERY_STRING)
    • @regilero 你能举个简短的例子吗?
    • 我认为@regilero 的意思类似于“RewriteRule .* - [E=key:SEKRITVALUE]”,然后是对 %{ENV:key} 的 RewriteCond 测试。但是,我无法让它工作......
    【解决方案3】:

    您可以在重写规则的末尾添加一个 [L],表示最后,或不再处理。这仅适用于 Apache 配置。它不适用于 .htaccess 文件。

    RewriteEngine On
    
    RewriteCond  %{REQUEST_URI}  pattern$
    RewriteRule .* /file.php [L]
    
    RewriteCond %{REQUEST_URI} file.php$
    RewriteRule .* /page-not-found.php [L]
    

    【讨论】:

    • 这不会阻止对file.php的访问吗?
    • 我只包括了一个重写规则作为示例。为了清楚起见,我添加了第二个。它们都是必需的。
    • 嗯,我无法让它在我的 Apache 2 上工作。你确定这能工作吗?
    • 也无法让它工作,这是我尝试的第一件事。
    • 我认为在 .htaccess 中会很好,但我想不是。如果你把它放在你的 httpd.conf(或虚拟主机)中,它确实可以工作。与处理 .htaccess 的方式有关。我已经用我在 Apache 配置中使用的内容再次更新了我的答案,并让它正常工作。我将发布另一个可能更简单的答案。
    【解决方案4】:

    仅使用 .htaccess 的更简单方法。

    将您的 file.php 移动到名为securedir 的新目录中。在根目录中使用这个 .htaccess 文件。

    RewriteEngine On
    RewriteRule ^pattern$ securedir/file.php
    

    使用 .htaccess 文件中的 this 防止访问securedir中的任何内容。 (如果您愿意,也可以将它们引导回不同的页面。)

    deny from all
    

    【讨论】:

    • 谢谢。除了在deny from all 之前,您还做了哪些 .htaccess 以了解它与securedir 目录有关?
    • 没有别的了。它进入secureir中自己的.htaccess文件。
    猜你喜欢
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 2011-02-10
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    相关资源
    最近更新 更多