.htaccess 中的条件 - 使用 mod_rewrite 测试环境变量

问题描述 投票:0回答:1

当设置两个条件时我想拒绝。

我已经在我的

apache2.conf
中设置了变量:

SetEnv MY_SITE stage

然后在

.htaccess
中我检查标头和环境变量是否匹配。

# check the variable is set by outputting to header. 
RewriteCond %{ENV:MY_SITE} (.+)
RewriteRule ^ - [E=MY_SITE:%1]
Header always set X-Site %{MY_SITE}e

如果标头错误,则拒绝访问,这是暂存:

# check the azure header and that this is staging
RewriteCond %{HTTP:X-Azure-FDID} !^xxxxxx$ [NC]
RewriteCond %{ENV:MY_SITE} =stage
RewriteRule ^ - [F]

但是第二个条件不会导致禁止消息。

如果我尝试这样做,它会起作用并拒绝访问:

RewriteCond %{HTTP:X-Azure-FDID} !^xxxxxx$ [NC]
# RewriteCond %{ENV:MY_SITE} =stage
RewriteRule ^ - [F]

但这并不:

RewriteCond %{ENV:MY_SITE} =stage
RewriteRule ^ - [F]

为什么第二个条件不起作用?

.htaccess mod-rewrite
1个回答
0
投票
SetEnv MY_SITE stage

SetEnv
(mod_env) 处理得太晚,mod_rewrite 无法接收它(mod_rewrite 处理得很早)。您需要使用
SetEnvIf
(mod_setenvif) 来设置环境变量,这会更早处理。

SetEnv
的文档中所述:

该指令设置的内部环境变量是在大多数早期请求处理指令运行后设置的,例如访问控制和 URI 到文件名映射。如果您设置的环境变量是作为处理早期阶段的输入(例如 RewriteRule 指令),则您应该使用 SetEnvIf 设置环境变量。

SetEnvIf
有不同的语法。要无条件地设置此值,您需要执行类似以下操作:

SetEnvIf ^ ^ MY_SITE=stage

第一个参数 (

^
) 是匹配任何请求标头的正则表达式。
^
总是成功的。

第二个参数(另一个

^
)是与前面的参数值匹配的正则表达式。再说一次,这总是成功的。

.htaccess
上下文中使用 env vars 和 mod_rewrite 时,您需要小心重写引擎的任何循环(例如,
.htaccess
文件中稍后的标准前端控制器模式可能会触发此操作)。如果重写引擎在第二遍时,在第一遍期间设置的任何环境变量都会使用
REDIRECT_
前缀重命名(例如
REDIRECT_MY_SITE
)。第三遍,
REDIRECT_REDIRECT_MY_SITE
等。因此,您可能需要检查
REDIRECT_<var>
,或者阻止重写引擎进行额外的遍历。 (默认情况下,servervirtualhost上下文中的mod_rewrite指令没有这种额外的复杂性。)


# check the variable is set by outputting to header. 
RewriteCond %{ENV:MY_SITE} (.+)
RewriteRule ^ - [E=MY_SITE:%1]
Header always set X-Site %{MY_SITE}e

鉴于上述情况,这并没有测试您认为它的作用。在这种情况下,mod_rewrite 规则不执行任何操作(因为处理此规则时未设置

MY_SITE
)。当
Header
被处理时(处理得很晚),
SetEnv
已经设置了环境变量。


替代使用
Define

我已经在我的

apache2.conf

中设置了变量

但是,由于您可以访问服务器配置,因此请考虑使用“已定义”变量(使用

Define
指令)而不是环境变量。变量不能在
.htaccess
中定义,但可以在
.htaccess
中测试它们,并且不会像环境变量(如上所述)那样“重命名”。

例如,在

apache2.conf
中:

Define MY_SITE stage

.htaccess

<IfDefine MY_SITE>
    RewriteCond %{HTTP:X-Azure-FDID} !^xxxxxx$ [NC]
    RewriteRule ^ - [F]
</IfDefine>

这显然并没有实际检查

MY_SITE
的值,因此假设它只会在登台服务器上设置(实际上是一个布尔值)。因此,最好将变量名称更改为类似
STAGING_SITE
的名称。

如果

MY_SITE
可以包含多个值,那么您可以根据需要检查该值:

<IfDefine MY_SITE>
    RewriteCond %{HTTP:X-Azure-FDID} !^xxxxxx$ [NC]
    RewriteCond ${MY_SITE} =stage
    RewriteRule ^ - [F]
</IfDefine>
© www.soinside.com 2019 - 2024. All rights reserved.