.htaccess RewriteCond,其中URI不包含域

时间:2021-05-29 11:18:20

I have looked around on Google and * for the answer to this question, but the fact that I don't know much about .htaccess doesn't help me decide what the correct answers for my situation are, so I am asking here.

我在谷歌和*上搜索过这个问题的答案,但是我对。htaccess知之甚少,这并不能帮助我确定正确的答案。

My situation is that I have several sites that are using the same physical directory as their root on the server.

我的情况是,我有几个站点在服务器上使用与其根目录相同的物理目录。

This is all working fine but I wanted to make sure that each site can't access each others images etc from the browser unless they are on the correct domain.

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

Currently I have a file structure like this:

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

/resources/{resource}/{full_domain_name}

So for example www.domain.co.uk would have a structure like this:

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

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

But if www.domain_2.co.uk exists using the same physical directory for the site root then they can look at other domain's resources from their own domain, like this:

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

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

This isn't really a major problem since there is absolutely no sensitive information stored in these directories, but it's more of an annoyance and I would rather users were not able to do it (not that anyone actually has so far).

这并不是真正的主要问题,因为这些目录中绝对没有存储敏感信息,但它更令人讨厌,我宁愿用户不能这样做(到目前为止,并不是所有人都有)。

I tried putting a .htaccess file into the /resources directory but I'm stuck with the regular expressions etc.

我尝试将.htaccess文件放到/resources目录中,但是我被正则表达式所困。

I basically want to make sure that the URI contains the current domain name otherwise redirect to a 403 error page.

我主要想确保URI包含当前的域名,否则会重定向到一个403错误页面。

This is what I came up with:

这就是我想到的:

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

The reason I put in the [^/] bit is because there are several folders, for example:

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

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

Could anybody help me with these conditions?

有人能帮我处理这些条件吗?

Any help would be appreciated.

如有任何帮助,我们将不胜感激。

2 个解决方案

#1


11  

This is terrific question and if I could I would have upvoted 10+ times. I am posting my answer even though you have an accepted answer here as I really had to dig through all my Apache resources to come up with the answer. Here is the rule you will need for this problem:

这是一个很棒的问题,如果我可以的话,我可以向上投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: Since we cannot use % variables on RHS as back-reference, I am using special regex back-reference variable \1 in the RewriteCond here.

PS:由于我们不能在RHS上使用%变量作为回引用,所以我在RewriteCond中使用了特殊的regex回引用变量\1。

#2


3  

This condition is insufficient:

这个条件是不够的:

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

Because if I request anything that doesn't start with /resources/, I'll get the 403.php error page. What you really want is something like this:

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

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

Or

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

Where the first condition is checking that the request is for a resource, then the second checking the host. HOWEVER, neither of these will work because mod_rewrite's RewriteCond directive doesn't allow % variables or backreferences in the right hand side of the condition, only the left. Likewise, you cannot do this either:

第一个条件是检查请求是否为资源,第二个条件是检查主机。但是,这两种方法都不起作用,因为mod_rewrite的RewriteCond指令不允许在条件的右边(只有左边)包含%变量或反向引用。同样,你也不能这样做:

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

Because the RewriteRule's expression cannot have variables in it, since it's a regex, and it literally expects a %{HTTP_HOST} instead of replacing it with the Host given in the request. So to conclude, no, you can't do this with mod_rewrite's conditions this way.

因为RewriteRule的表达式中不能有变量,因为它是一个regex,而且它确实需要一个%{HTTP_HOST},而不是用请求中给定的主机替换它。总结一下,不,你不能用mod_rewrite的条件。

Something that you can try if you have access to either server config or vhost config is to create a RewriteMap and pass in both the %{REQUEST_URI} and %{HTTP_HOST}. So if your map is called check_host then your rule may look something like this:

如果可以访问服务器配置或vhost配置,那么可以尝试创建RewriteMap并同时传入%{REQUEST_URI}和%{HTTP_HOST}。如果你的映射被称为check_host,那么你的规则可能是这样的:

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

And your script will just need to parse the input, split it from the first _, parse the request URI and make sure the host is the same as the HTTP_HOST. If it's the same, output the same request URI, otherwise output the error URI. If you don't have access to server or vhost config, I think you're out of luck. RewriteMap cannot be defined in the htaccess file.

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

#1


11  

This is terrific question and if I could I would have upvoted 10+ times. I am posting my answer even though you have an accepted answer here as I really had to dig through all my Apache resources to come up with the answer. Here is the rule you will need for this problem:

这是一个很棒的问题,如果我可以的话,我可以向上投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: Since we cannot use % variables on RHS as back-reference, I am using special regex back-reference variable \1 in the RewriteCond here.

PS:由于我们不能在RHS上使用%变量作为回引用,所以我在RewriteCond中使用了特殊的regex回引用变量\1。

#2


3  

This condition is insufficient:

这个条件是不够的:

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

Because if I request anything that doesn't start with /resources/, I'll get the 403.php error page. What you really want is something like this:

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

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

Or

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

Where the first condition is checking that the request is for a resource, then the second checking the host. HOWEVER, neither of these will work because mod_rewrite's RewriteCond directive doesn't allow % variables or backreferences in the right hand side of the condition, only the left. Likewise, you cannot do this either:

第一个条件是检查请求是否为资源,第二个条件是检查主机。但是,这两种方法都不起作用,因为mod_rewrite的RewriteCond指令不允许在条件的右边(只有左边)包含%变量或反向引用。同样,你也不能这样做:

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

Because the RewriteRule's expression cannot have variables in it, since it's a regex, and it literally expects a %{HTTP_HOST} instead of replacing it with the Host given in the request. So to conclude, no, you can't do this with mod_rewrite's conditions this way.

因为RewriteRule的表达式中不能有变量,因为它是一个regex,而且它确实需要一个%{HTTP_HOST},而不是用请求中给定的主机替换它。总结一下,不,你不能用mod_rewrite的条件。

Something that you can try if you have access to either server config or vhost config is to create a RewriteMap and pass in both the %{REQUEST_URI} and %{HTTP_HOST}. So if your map is called check_host then your rule may look something like this:

如果可以访问服务器配置或vhost配置,那么可以尝试创建RewriteMap并同时传入%{REQUEST_URI}和%{HTTP_HOST}。如果你的映射被称为check_host,那么你的规则可能是这样的:

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

And your script will just need to parse the input, split it from the first _, parse the request URI and make sure the host is the same as the HTTP_HOST. If it's the same, output the same request URI, otherwise output the error URI. If you don't have access to server or vhost config, I think you're out of luck. RewriteMap cannot be defined in the htaccess file.

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