如何编写IF包含条件匹配的2个通过RewriteRules设置的ENV变量

时间:2019-02-21 19:35:53

标签: apache mod-rewrite httpd.conf mod-env

要提供具体背景,目标是:

使用apache httpd,我需要测试请求uri的上下文段是否包含在标头中发送的cookie值中,然后再将用户重定向到初始页面以进行cookie确认或允许他们访问该网站。

提供以下信息:

URL: http://www.example.com/en/gb/main.html

cookie:; acceptedCookies = fr,en,de,it

如果url的语言段=“ en”,并且这是用户接受的Cookie。然后允许用户访问主站点,否则将用户重定向到初始页面。

我尝试过的事情:

SetEnvIf Host ^ uriCountryCode=NUL
SetEnvIfNoCase Request_URI "^(.+)?\/([a-zA-Z]{2})\/[a-zA-Z]{2}\/.+$" uriCountryCode=$2

SetEnvIf Host ^ acceptedCookieList=EMP 
SetEnvIf Cookie "(^|;\*)acceptedCookies=([^;]+)?" acceptedCookieList=$2
#1st.
<If "%{acceptedCookieList} =~ %{uriCountryCode}">
// Doesn't work
</If>

#2nd.
<If "env('acceptedCookieList') =~ env('uriCountryCode')">
// No luck
</If>

#3rd.
<If "env('acceptedCookieList') =~ /env('uriCountryCode')/">
// Now I'm just guessing
</If>

#4th.
RewriteCond %{acceptedCookieList} !%{uriCountryCode}
RewriteCond %{REQUEST_URI} !^/en/gb/splash.html$ [NC]
RewriteRule ^(.+)$ /mt/en/splash [L,R=301]

我最近了解到,由于SetEnvIf变量未尽早加载而无法访问,因此其中的一些模块(即env('x'))不会加载SetEnvIf变量,但我正在尝试为此找到httpd解决方案我的问题

2 个答案:

答案 0 :(得分:1)

  1. mod_rewrite可以set environment variables
  2. 使用302 redirect(临时移动)代替301 redirect(永久移动)。
  3. 与客户端提供的任意正则表达式(即acceptedCookies cookie的内容)进行匹配非常危险。不过,httpd expressions语言没有内置的“包含”功能,因此如何避免正则表达式匹配并不明显。这将使您的服务器容易受到DoS attacks的攻击。<​​/ li>

所有这些,请考虑以下内容:

RewriteCond %{HTTP_COOKIE} acceptedCookies=([^;]+)
RewriteRule ^.*$ - [E=COOKIE_ACCEPTED_LANGS:%1]

RewriteCond %{REQUEST_URI} ^/([^/]+)/.*$
RewriteRule ^.*$ - [E=URL_LANG:%1]

RewriteCond expr %{ENV:URL_LANG} =~ %{ENV:COOKIE_ACCEPTED_LANGS}
RewriteCond %{REQUEST_URI} !^/en/gb/splash.html$ [NC]
RewriteRule ^.*$ /mt/en/splash [R]

答案 1 :(得分:0)

下面的@Avi解决方案可以使用,但是任何允许长度未知的客户端值执行验证的解决方案从根本上都是有缺陷的,存在超过缓冲区和DOS的潜在风险。