Как я могу получить доступ к переменной среды, установленной правилом перезаписи в выражении?
Я работаю над приложением Symfony 3.4, которое имеет открытую и закрытую части. Однако в настоящее время я настраиваю промежуточную систему для этого приложения, к которой должны обращаться только авторизованные пользователи, поэтому я поставил базовую аутентификацию.htaccess перед всем приложением.
В приложении существует один маршрут, к которому должно обращаться внешнее приложение, которое не обеспечивает аутентификацию. Я хочу отключить аутентификацию.htaccess только для этого единственного маршрута. Все URL для этого маршрута имеют вид /api/post-result/123
где 123
это произвольный идентификатор
После поиска вокруг, я попытался решить эту проблему с помощью 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): [...] установка переменной env 'SFURI' в значение 'api / post-result / 123'
[rewrite: trace1] [pid 12755] mod_rewrite.c (476): [...] внутреннее перенаправление с /app.php [INTERNAL REDIRECT]
Однако по какой-то причине переменная пуста, когда я пытаюсь получить к ней доступ позже. Возможно ли, что все переменные среды очищаются при внутреннем перенаправлении, вызванном последним правилом перезаписи? Журнал показывает, что условие не совпадает, и когда я изменяю условие, чтобы проверить, является ли переменная пустой, условие возвращается как истинное. Я также пытался использовать 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_"?