![如何访问表达式中的重写规则设置的环境变量?](https://linux22.com/image/731494/%E5%A6%82%E4%BD%95%E8%AE%BF%E9%97%AE%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%B8%AD%E7%9A%84%E9%87%8D%E5%86%99%E8%A7%84%E5%88%99%E8%AE%BE%E7%BD%AE%E7%9A%84%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%EF%BC%9F.png)
我正在开发一个 Symfony 3.4 应用程序,它包含公共和私有部分。但是,我目前正在为该应用程序设置一个暂存系统,该系统只能由授权用户访问,因此我在整个应用程序前面放置了一个 .htaccess 基本身份验证。
应用程序中只有一条路由需要由不提供身份验证的外部应用程序访问。我想仅针对此一条路由禁用 .htaccess 身份验证。此路由的所有 URL 都采用以下形式,/api/post-result/123
其中123
是任意 ID。
经过一番搜索后,我尝试通过Require expr
.htaccess 中的一个条目来解决这个问题,该条目只会匹配 URL。但是,由于 Symfony 会进行 URL 重写,因此REQUEST_URI
在服务器上始终显示为“app.php”(以及我的条件)。我尝试了其他变量,例如QUERY_STRING
或PATH_INFO
,但它们似乎都不包含我的实际请求 URI。然后,我尝试使用重写规则将匹配的 URI 放入环境变量中。但是,似乎表达式无法读取它。
这是我的 .htaccess 文件
DirectoryIndex app.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule ^(.*)$ %{ENV:BASE}/app.php [L,E=SFURI:$1] # <-- env variable is set here
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
RedirectMatch 302 ^/$ /app.php/
</IfModule>
</IfModule>
<Files "*.php">
AuthUserFile /srv/my/app/.htuser
AuthName "Authentication Required"
AuthType Basic
# allow access to post-result api without authentication
# THIS DOES NOT WORK as reqenv('SFURI') is always empty
Require expr "reqenv('SFURI') =~ m#/api/post-result/.*$#"
# require authentication for everything else
Require valid-user
</Files>
查看Apache日志,环境变量设置正确:
[rewrite:trace5] [pid 11010] mod_rewrite.c(476): [...] 将环境变量“SFURI”设置为“api/post-result/123”
[rewrite:trace1] [pid 12755] mod_rewrite.c(476): [...] 使用 /app.php 进行内部重定向 [内部重定向]
但是,由于某种原因,当我稍后尝试访问变量时,它为空。 是否有可能在由上一个重写规则导致的内部重定向上清除了所有环境变量? 日志显示条件不匹配,当我更改条件以检查变量是否为空时,条件返回为真。 我也尝试过使用函数env
代替reqenv
,但行为是一样的。
[authz_core:trace4] [pid 11010] util_expr_eval.c(860): [...] /srv/my/app/.htaccess:36 中的表达式求值得出:0
[authz_core:debug] [pid 11010] mod_authz_core.c(809): [...] AH01626: Require expr“reqenv('SFURI') =~ m#/api/post-result/.*$#”的授权结果被拒绝
我该怎么做才能让我的表达式找到重写规则设置的环境变量?
答案1
事实证明,最后一条重写规则导致的内部重定向会为所有变量添加前缀REDIRECT_
。为了访问表达式中的变量,需要将其作为 进行访问REDIRECT_SFURI
。
StackOverflow 上也讨论过这个问题:在 Apache RewriteRule 指令中设置环境变量时,是什么原因导致变量名称以“REDIRECT_”为前缀?