首先有效的规则是:
DirectoryIndex index.php
ErrorDocument 403 /form.html
RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule . - [F,L]
这意味着http://example.com
并且http://example.com/index.php
只能通过 打开POST
。
现在的问题是
我添加了以下附加规则集:
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]
现在,我再次发送 POSThttp://example.com
但收到此错误:
Forbidden
You don't have permission to access / on this server.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.
这没有意义,因为规则不应该在index.php
发送 403 时捕获请求,但是好吧,我扩展了第二条规则如下:
RewriteCond %{REQUEST_URI} !^/form\.html$
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]
并再次发送 POST 至http://example.com没有返回 500,但我仍然收到 403?!
更新 1
如果我删除第一个规则集,第二个规则集将按预期单独运行。这意味着只有http://example.com
、http://example.com/index.php
和http://example.com/form.html
可以访问。
更新 2
如果我使用这两组规则并发送我的 POST 至,http://example.com/index.php
我不会收到任何错误?!
因此,仅当我向根 URL 发送 POST 时,规则才会干扰。但为什么呢?
答案1
RewriteCond %{REQUEST_URI} ^/index\.php$ RewriteCond %{REQUEST_METHOD} !POST RewriteRule . - [F,L]
假设您的DirectoryIndex
设置为index.php
并且您没有其他指令,那么似乎是您的第一个规则块导致访问 时出现 403 Forbidden http://example.com/
。以上仅允许直接对 发出 POST 请求/index.php
。
这RewriteRule
图案(单个点)在上述中完全阻止了对 的请求的规则处理http://example.com/
。然后,mod_dir 启动对 的内部子请求/index.php
。请注意,此子请求实际上显示为内部 GET 请求(REQUEST_METHOD
服务器变量设置为该请求),因此上述条件(!POST
)成功,请求最终被禁止。
最好将请求规范化,并将任何 请求从外部重定向(308 - 永久重定向,保留请求方法)到/index.php
。/
然后,您可以集中精力匹配/
,而忽略子请求。
# Exception for error document (before other directives)
RewriteRule ^form\.html$ - [L]
# Canonicalise URL and remove "index.php" if requested
RewriteRule %{REDIRECT_STATUS} ^$
RewriteRule ^index\.php$ / [R=308,L]
# Only allow POST requests to the document root
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule ^$ - [F]
(使用L
时不需要标志。是隐含的。)F
L
测试前请确保浏览器缓存已清除。(最好使用R=307
(临时)重定向进行测试以避免缓存。)
RewriteCond %{REQUEST_URI} !^/index\.php$ RewriteRule . - [F,L]
正如您所建议的,这并不与上述规则冲突,它匹配除/
and之外的任何内容/index.php
(在 中使用时.htaccess
)。因此,这将禁止访问所有其他 URL,无论请求方法如何。(如上所述,它似乎是访问 时触发 403 的第一条规则http://example.com/
。)只要您为错误文档包含例外情况(如上所述),那么您无需添加其他条件。