13

我在 Google 和 StackOverflow 上四处寻找这个问题的答案,但我对 .htaccess 了解不多这一事实并不能帮助我确定适合我的情况的正确答案是什么,所以我在这里问。

我的情况是我有几个站点在服务器上使用相同的物理目录作为它们的根目录。

这一切都很好,但我想确保每个站点都无法从浏览器访问彼此的图像等,除非它们位于正确的域中。

目前我有一个这样的文件结构:

/resources/{resource}/{full_domain_name}

因此,例如www.domain.co.uk会有这样的结构:

http://www.domain.co.uk/resources/images/www.domain.co.uk/some_image.jpg

但是如果www.domain_2.co.uk存在使用相同的物理目录作为站点根目录,那么他们可以从自己的域中查看其他域的资源,如下所示:

http://www.domain_2.co.uk/resources/images/www.domain.co.uk/some_image.jpg

这并不是一个真正的主要问题,因为这些目录中绝对没有存储任何敏感信息,但这更令人烦恼,我宁愿用户无法做到这一点(到目前为止,实际上没有人这样做)。

我尝试将 .htaccess 文件放入 /resources 目录,但我坚持使用正则表达式等。

我基本上想确保 URI 包含当前域名,否则重定向到 403 错误页面。

这就是我想出的:

RewriteCond %{REQUEST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$
RewriteRule ^(.*)$ /error/403.php

我放在[^/]位的原因是因为有几个文件夹,例如:

/resources/images/{full_domain_name}
/resources/scripts/{full_domain_name}
/resources/stylesheets/{full_domain_name}

有人可以帮我解决这些条件吗?

任何帮助,将不胜感激。

4

2 回答 2

11

这是一个了不起的问题,如果可以的话,我会投票超过 10 次。即使您在这里有一个接受的答案,我也会发布我的答案,因为我真的必须挖掘我所有的 Apache 资源才能得出答案。这是解决此问题所需的规则:

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /

RewriteCond %{HTTP_HOST}:%{REQUEST_URI} !^([^:]+):/resources/[^/]+/\1/.+ [NC]
RewriteRule ^resources/[^/]+/[^/]+/.+ - [F,NC,NE]

PS:由于我们不能使用%RHS 上的变量作为反向引用,我在这里使用特殊的正则表达式反向引用\1变量RewriteCond

于 2012-06-17T18:01:12.037 回答
3

这个条件是不充分的:

RewriteCond %{REQUEUST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$

因为如果我请求任何不以 开头的内容/resources/,我将得到 403.php 错误页面。你真正想要的是这样的:

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteCond %{HTTP_HOST} !%1

或者

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteCond %{REQUEST_URI} !^/resources/[^/]+/%{HTTP_HOST}/

第一个条件是检查请求是否针对资源,然后第二个条件是检查主机。但是,这些都不起作用,因为 mod_rewrite 的RewriteCond指令不允许条件右侧的%变量或反向引用,只有左侧。同样,您也不能这样做:

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteRule !^/resources/[^/]+/%{HTTP_HOST}/ /error/403.php

因为 RewriteRule 的表达式中不能包含变量,因为它是一个正则表达式,并且它实际上期望 a%{HTTP_HOST}而不是用请求中给出的 Host 替换它。所以总而言之,不,你不能以这种方式使用 mod_rewrite 的条件来做到这一点。

如果您有权访问服务器配置或虚拟主机配置,您可以尝试创建一个RewriteMap并同时传入%{REQUEST_URI}%{HTTP_HOST}. 因此,如果您的地图被调用check_host,那么您的规则可能如下所示:

RewriteRule ^resources/[^/]+/([^/]+)/ ${check_host:%{HTTP_HOST}_%{REQUEST_URI}}

您的脚本只需要解析输入,将其从第一个拆分_,解析请求 URI 并确保主机与 HTTP_HOST 相同。如果相同,则输出相同的请求URI,否则输出错误URI。如果您无权访问服务器或虚拟主机配置,我认为您不走运。不能在 htaccess 文件中定义 RewriteMap。

于 2012-06-17T08:41:18.217 回答