mod_rewrite:允许redirect但阻止直接访问

我目前正在使用mod_rewrite做一个内部redirect

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

不过,我想阻止直接访问file.php通过redirect到该文件的请求到页面未find的URL。

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

问题是第二个规则也适用于我做第一次redirect,因此打破了我的第一个内部redirect。

[问]有没有办法让第一个redirect,但防止直接访问redirect的文件?

编辑:启发@ 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] 

当然,使用一个更复杂的键,只有内部重定向! 否则,用户将能够获取密钥。

使用ENV:REDIRECT_STATUS变量(请参阅mromaine对“mod_rewrite隐藏功能”社区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。

您可以在重写规则末尾添加[L],表示Last,或者不再进行处理。 这只会在Apache配置里面工作。 它不能在.htaccess文件中工作。

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

一个简单的方法来做到这一点只使用.htaccess。

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

 RewriteEngine On RewriteRule ^pattern$ securedir/file.php 

在那里的.htaccess文件中阻止访问任何有保证的内容。 (或者,如果你愿意的话,可以把它们指向不同的页面。)

 deny from all